PageRenderTime 28ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/test/java/io/File/SymLinks.java

https://github.com/ikeji/openjdk7-jdk
Java | 374 lines | 257 code | 59 blank | 58 comment | 42 complexity | 2b5a0da3ab6c24c5c88e0e8c835cae7c MD5 | raw file
  1. /*
  2. * Copyright (c) 2009, 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. /* @test
  24. * @bug 6595866
  25. * @summary Test java.io.File operations with sym links
  26. */
  27. import java.io.*;
  28. import java.nio.file.*;
  29. import java.nio.file.attribute.*;
  30. import static java.nio.file.LinkOption.*;
  31. public class SymLinks {
  32. final static PrintStream out = System.out;
  33. final static File top = new File(System.getProperty("test.dir", "."));
  34. // files used by the test
  35. final static File file = new File(top, "foofile");
  36. final static File link2file = new File(top, "link2file");
  37. final static File link2link2file = new File(top, "link2link2file");
  38. final static File dir = new File(top, "foodir");
  39. final static File link2dir = new File(top, "link2dir");
  40. final static File link2link2dir = new File(top, "link2link2dir");
  41. final static File link2nobody = new File(top, "link2nobody");
  42. final static File link2link2nobody = new File(top, "link2link2nobody");
  43. /**
  44. * Setup files, directories, and sym links used by test.
  45. */
  46. static void setup() throws IOException {
  47. // link2link2file -> link2file -> foofile
  48. FileOutputStream fos = new FileOutputStream(file);
  49. try {
  50. fos.write(new byte[16*1024]);
  51. } finally {
  52. fos.close();
  53. }
  54. mklink(link2file, file);
  55. mklink(link2link2file, link2file);
  56. // link2link2dir -> link2dir -> dir
  57. assertTrue(dir.mkdir());
  58. mklink(link2dir, dir);
  59. mklink(link2link2dir, link2dir);
  60. // link2link2nobody -> link2nobody -> <does-not-exist>
  61. mklink(link2nobody, new File(top, "DoesNotExist"));
  62. mklink(link2link2nobody, link2nobody);
  63. }
  64. /**
  65. * Remove files, directories, and sym links used by test.
  66. */
  67. static void cleanup() throws IOException {
  68. if (file != null)
  69. file.delete();
  70. if (link2file != null)
  71. Files.deleteIfExists(link2file.toPath());
  72. if (link2link2file != null)
  73. Files.deleteIfExists(link2link2file.toPath());
  74. if (dir != null)
  75. dir.delete();
  76. if (link2dir != null)
  77. Files.deleteIfExists(link2dir.toPath());
  78. if (link2link2dir != null)
  79. Files.deleteIfExists(link2link2dir.toPath());
  80. if (link2nobody != null)
  81. Files.deleteIfExists(link2nobody.toPath());
  82. if (link2link2nobody != null)
  83. Files.deleteIfExists(link2link2nobody.toPath());
  84. }
  85. /**
  86. * Creates a sym link source->target
  87. */
  88. static void mklink(File source, File target) throws IOException {
  89. Files.createSymbolicLink(source.toPath(), target.toPath());
  90. }
  91. /**
  92. * Returns true if the "link" exists and is a sym link.
  93. */
  94. static boolean isSymLink(File link) {
  95. return Files.isSymbolicLink(link.toPath());
  96. }
  97. /**
  98. * Returns the last modified time of a sym link.
  99. */
  100. static long lastModifiedOfSymLink(File link) throws IOException {
  101. BasicFileAttributes attrs =
  102. Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
  103. assertTrue(attrs.isSymbolicLink());
  104. return attrs.lastModifiedTime().toMillis();
  105. }
  106. /**
  107. * Returns true if sym links are supported on the file system where
  108. * "dir" exists.
  109. */
  110. static boolean supportsSymLinks(File dir) {
  111. Path link = dir.toPath().resolve("link");
  112. Path target = dir.toPath().resolve("target");
  113. try {
  114. Files.createSymbolicLink(link, target);
  115. Files.delete(link);
  116. return true;
  117. } catch (UnsupportedOperationException x) {
  118. return false;
  119. } catch (IOException x) {
  120. return false;
  121. }
  122. }
  123. static void assertTrue(boolean v) {
  124. if (!v) throw new RuntimeException("Test failed");
  125. }
  126. static void assertFalse(boolean v) {
  127. assertTrue(!v);
  128. }
  129. static void header(String h) {
  130. out.println();
  131. out.println();
  132. out.println("-- " + h + " --");
  133. }
  134. /**
  135. * Tests go here.
  136. */
  137. static void go() throws IOException {
  138. // check setup
  139. assertTrue(file.isFile());
  140. assertTrue(isSymLink(link2file));
  141. assertTrue(isSymLink(link2link2file));
  142. assertTrue(dir.isDirectory());
  143. assertTrue(isSymLink(link2dir));
  144. assertTrue(isSymLink(link2link2dir));
  145. assertTrue(isSymLink(link2nobody));
  146. assertTrue(isSymLink(link2link2nobody));
  147. header("createNewFile");
  148. assertFalse(file.createNewFile());
  149. assertFalse(link2file.createNewFile());
  150. assertFalse(link2link2file.createNewFile());
  151. assertFalse(dir.createNewFile());
  152. assertFalse(link2dir.createNewFile());
  153. assertFalse(link2link2dir.createNewFile());
  154. assertFalse(link2nobody.createNewFile());
  155. assertFalse(link2link2nobody.createNewFile());
  156. header("mkdir");
  157. assertFalse(file.mkdir());
  158. assertFalse(link2file.mkdir());
  159. assertFalse(link2link2file.mkdir());
  160. assertFalse(dir.mkdir());
  161. assertFalse(link2dir.mkdir());
  162. assertFalse(link2link2dir.mkdir());
  163. assertFalse(link2nobody.mkdir());
  164. assertFalse(link2link2nobody.mkdir());
  165. header("delete");
  166. File link = new File(top, "mylink");
  167. try {
  168. mklink(link, file);
  169. assertTrue(link.delete());
  170. assertTrue(!isSymLink(link));
  171. assertTrue(file.exists());
  172. mklink(link, link2file);
  173. assertTrue(link.delete());
  174. assertTrue(!isSymLink(link));
  175. assertTrue(link2file.exists());
  176. mklink(link, dir);
  177. assertTrue(link.delete());
  178. assertTrue(!isSymLink(link));
  179. assertTrue(dir.exists());
  180. mklink(link, link2dir);
  181. assertTrue(link.delete());
  182. assertTrue(!isSymLink(link));
  183. assertTrue(link2dir.exists());
  184. mklink(link, link2nobody);
  185. assertTrue(link.delete());
  186. assertTrue(!isSymLink(link));
  187. assertTrue(isSymLink(link2nobody));
  188. } finally {
  189. Files.deleteIfExists(link.toPath());
  190. }
  191. header("renameTo");
  192. File newlink = new File(top, "newlink");
  193. assertTrue(link2file.renameTo(newlink));
  194. try {
  195. assertTrue(file.exists());
  196. assertTrue(isSymLink(newlink));
  197. assertTrue(!isSymLink(link2file));
  198. } finally {
  199. newlink.renameTo(link2file); // restore link
  200. }
  201. assertTrue(link2dir.renameTo(newlink));
  202. try {
  203. assertTrue(dir.exists());
  204. assertTrue(isSymLink(newlink));
  205. assertTrue(!isSymLink(link2dir));
  206. } finally {
  207. newlink.renameTo(link2dir); // restore link
  208. }
  209. header("list");
  210. final String name = "entry";
  211. File entry = new File(dir, name);
  212. try {
  213. assertTrue(dir.list().length == 0); // directory should be empty
  214. assertTrue(link2dir.list().length == 0);
  215. assertTrue(link2link2dir.list().length == 0);
  216. assertTrue(entry.createNewFile());
  217. assertTrue(dir.list().length == 1);
  218. assertTrue(dir.list()[0].equals(name));
  219. // access directory by following links
  220. assertTrue(link2dir.list().length == 1);
  221. assertTrue(link2dir.list()[0].equals(name));
  222. assertTrue(link2link2dir.list().length == 1);
  223. assertTrue(link2link2dir.list()[0].equals(name));
  224. // files that are not directories
  225. assertTrue(link2file.list() == null);
  226. assertTrue(link2nobody.list() == null);
  227. } finally {
  228. entry.delete();
  229. }
  230. header("isXXX");
  231. assertTrue(file.isFile());
  232. assertTrue(link2file.isFile());
  233. assertTrue(link2link2file.isFile());
  234. assertTrue(dir.isDirectory());
  235. assertTrue(link2dir.isDirectory());
  236. assertTrue(link2link2dir.isDirectory());
  237. // on Windows we test with the DOS hidden attribute set
  238. if (System.getProperty("os.name").startsWith("Windows")) {
  239. DosFileAttributeView view = Files
  240. .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
  241. view.setHidden(true);
  242. try {
  243. assertTrue(file.isHidden());
  244. assertTrue(link2file.isHidden());
  245. assertTrue(link2link2file.isHidden());
  246. } finally {
  247. view.setHidden(false);
  248. }
  249. assertFalse(file.isHidden());
  250. assertFalse(link2file.isHidden());
  251. assertFalse(link2link2file.isHidden());
  252. }
  253. header("length");
  254. long len = file.length();
  255. assertTrue(len > 0L);
  256. // these tests should follow links
  257. assertTrue(link2file.length() == len);
  258. assertTrue(link2link2file.length() == len);
  259. assertTrue(link2nobody.length() == 0L);
  260. header("lastModified / setLastModified");
  261. // need time to diff between link and file
  262. long origLastModified = file.lastModified();
  263. assertTrue(origLastModified != 0L);
  264. try { Thread.sleep(2000); } catch (InterruptedException x) { }
  265. file.setLastModified(System.currentTimeMillis());
  266. long lastModified = file.lastModified();
  267. assertTrue(lastModified != origLastModified);
  268. assertTrue(lastModifiedOfSymLink(link2file) != lastModified);
  269. assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified);
  270. assertTrue(link2file.lastModified() == lastModified);
  271. assertTrue(link2link2file.lastModified() == lastModified);
  272. assertTrue(link2nobody.lastModified() == 0L);
  273. origLastModified = dir.lastModified();
  274. assertTrue(origLastModified != 0L);
  275. dir.setLastModified(0L);
  276. assertTrue(dir.lastModified() == 0L);
  277. assertTrue(link2dir.lastModified() == 0L);
  278. assertTrue(link2link2dir.lastModified() == 0L);
  279. dir.setLastModified(origLastModified);
  280. header("setXXX / canXXX");
  281. assertTrue(file.canRead());
  282. assertTrue(file.canWrite());
  283. assertTrue(link2file.canRead());
  284. assertTrue(link2file.canWrite());
  285. assertTrue(link2link2file.canRead());
  286. assertTrue(link2link2file.canWrite());
  287. if (file.setReadOnly()) {
  288. assertFalse(file.canWrite());
  289. assertFalse(link2file.canWrite());
  290. assertFalse(link2link2file.canWrite());
  291. assertTrue(file.setWritable(true)); // make writable
  292. assertTrue(file.canWrite());
  293. assertTrue(link2file.canWrite());
  294. assertTrue(link2link2file.canWrite());
  295. assertTrue(link2file.setReadOnly()); // make read only
  296. assertFalse(file.canWrite());
  297. assertFalse(link2file.canWrite());
  298. assertFalse(link2link2file.canWrite());
  299. assertTrue(link2link2file.setWritable(true)); // make writable
  300. assertTrue(file.canWrite());
  301. assertTrue(link2file.canWrite());
  302. assertTrue(link2link2file.canWrite());
  303. }
  304. }
  305. public static void main(String[] args) throws IOException {
  306. if (supportsSymLinks(top)) {
  307. try {
  308. setup();
  309. go();
  310. } finally {
  311. cleanup();
  312. }
  313. }
  314. }
  315. }