Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/nio/file/Files/CopyAndMove.java
38828 views
/*1* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 4313887 6838333 6917021 7006126 6950237 800664525* @summary Unit test for java.nio.file.Files copy and move methods26* @library ..27* @build CopyAndMove PassThroughFileSystem28* @run main/othervm CopyAndMove29* @key randomness30*/3132import java.nio.ByteBuffer;33import java.nio.file.*;34import static java.nio.file.Files.*;35import static java.nio.file.StandardCopyOption.*;36import static java.nio.file.LinkOption.*;37import java.nio.file.attribute.*;38import java.io.*;39import java.util.*;40import java.util.concurrent.TimeUnit;4142public class CopyAndMove {43static final Random rand = new Random();44static boolean heads() { return rand.nextBoolean(); }45private static boolean testPosixAttributes = false;4647public static void main(String[] args) throws Exception {48Path dir1 = TestUtil.createTemporaryDirectory();49try {5051// Same directory52testPosixAttributes = getFileStore(dir1).supportsFileAttributeView("posix");53testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));54testMove(dir1, dir1, TestUtil.supportsLinks(dir1));5556// Different directories. Use test.dir if possible as it might be57// a different volume/file system and so improve test coverage.58String testDir = System.getProperty("test.dir", ".");59Path dir2 = TestUtil.createTemporaryDirectory(testDir);60try {61boolean testSymbolicLinks =62TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);63testPosixAttributes = getFileStore(dir1).supportsFileAttributeView("posix") &&64getFileStore(dir2).supportsFileAttributeView("posix");65testCopyFileToFile(dir1, dir2, testSymbolicLinks);66testMove(dir1, dir2, testSymbolicLinks);67} finally {68TestUtil.removeAll(dir2);69}7071// Target is location associated with custom provider72Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());73testPosixAttributes = getFileStore(dir1).supportsFileAttributeView("posix") &&74getFileStore(dir3).supportsFileAttributeView("posix");75testCopyFileToFile(dir1, dir3, false);76testMove(dir1, dir3, false);7778// Test copy(InputStream,Path) and copy(Path,OutputStream)79testCopyInputStreamToFile();80testCopyFileToOuputStream();8182} finally {83TestUtil.removeAll(dir1);84}85}8687static void checkBasicAttributes(BasicFileAttributes attrs1,88BasicFileAttributes attrs2)89{90// check file type91assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());92assertTrue(attrs1.isDirectory() == attrs2.isDirectory());93assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());94assertTrue(attrs1.isOther() == attrs2.isOther());9596// check last modified time if not a symbolic link97if (!attrs1.isSymbolicLink()) {98long time1 = attrs1.lastModifiedTime().to(TimeUnit.SECONDS);99long time2 = attrs2.lastModifiedTime().to(TimeUnit.SECONDS);100101if (time1 != time2) {102System.err.format("File time for %s is %s\n", attrs1.fileKey(), attrs1.lastModifiedTime());103System.err.format("File time for %s is %s\n", attrs2.fileKey(), attrs2.lastModifiedTime());104assertTrue(false);105}106}107108// check size109if (attrs1.isRegularFile())110assertTrue(attrs1.size() == attrs2.size());111}112113static void checkPosixAttributes(PosixFileAttributes attrs1,114PosixFileAttributes attrs2)115{116assertTrue(attrs1.permissions().equals(attrs2.permissions()));117assertTrue(attrs1.owner().equals(attrs2.owner()));118assertTrue(attrs1.group().equals(attrs2.group()));119}120121static void checkDosAttributes(DosFileAttributes attrs1,122DosFileAttributes attrs2)123{124assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());125assertTrue(attrs1.isHidden() == attrs2.isHidden());126assertTrue(attrs1.isSystem() == attrs2.isSystem());127}128129static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,130Map<String,ByteBuffer> attrs2)131{132assert attrs1.size() == attrs2.size();133for (String name: attrs1.keySet()) {134ByteBuffer bb1 = attrs1.get(name);135ByteBuffer bb2 = attrs2.get(name);136assertTrue(bb2 != null);137assertTrue(bb1.equals(bb2));138}139}140141static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)142throws IOException143{144UserDefinedFileAttributeView view =145getFileAttributeView(file, UserDefinedFileAttributeView.class);146Map<String,ByteBuffer> result = new HashMap<>();147for (String name: view.list()) {148int size = view.size(name);149ByteBuffer bb = ByteBuffer.allocate(size);150int n = view.read(name, bb);151assertTrue(n == size);152bb.flip();153result.put(name, bb);154}155return result;156}157158// move source to target with verification159static void moveAndVerify(Path source, Path target, CopyOption... options)160throws IOException161{162// read attributes before file is moved163BasicFileAttributes basicAttributes = null;164PosixFileAttributes posixAttributes = null;165DosFileAttributes dosAttributes = null;166Map<String,ByteBuffer> namedAttributes = null;167168// get file attributes of source file169String os = System.getProperty("os.name");170if (os.startsWith("Windows")) {171dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);172basicAttributes = dosAttributes;173} else {174posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);175basicAttributes = posixAttributes;176}177if (basicAttributes == null)178basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);179180// hash file contents if regular file181int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;182183// record link target if symbolic link184Path linkTarget = null;185if (basicAttributes.isSymbolicLink())186linkTarget = readSymbolicLink(source);187188// read named attributes if available (and file is not a sym link)189if (!basicAttributes.isSymbolicLink() &&190getFileStore(source).supportsFileAttributeView("xattr"))191{192namedAttributes = readUserDefinedFileAttributes(source);193}194195// move file196Path result = move(source, target, options);197assertTrue(result == target);198199// verify source does not exist200assertTrue(notExists(source));201202// verify file contents203if (basicAttributes.isRegularFile()) {204if (computeHash(target) != hash)205throw new RuntimeException("Failed to verify move of regular file");206}207208// verify link target209if (basicAttributes.isSymbolicLink()) {210if (!readSymbolicLink(target).equals(linkTarget))211throw new RuntimeException("Failed to verify move of symbolic link");212}213214// verify basic attributes215checkBasicAttributes(basicAttributes,216readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));217218// verify other attributes when same provider219if (source.getFileSystem().provider() == target.getFileSystem().provider()) {220221// verify POSIX attributes222if (posixAttributes != null &&223!basicAttributes.isSymbolicLink() &&224testPosixAttributes)225{226checkPosixAttributes(posixAttributes,227readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));228}229230// verify DOS attributes231if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {232DosFileAttributes attrs =233readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);234checkDosAttributes(dosAttributes, attrs);235}236237// verify named attributes238if (namedAttributes != null &&239getFileStore(target).supportsFileAttributeView("xattr"))240{241checkUserDefinedFileAttributes(namedAttributes,242readUserDefinedFileAttributes(target));243}244}245}246247/**248* Tests all possible ways to invoke move249*/250static void testMove(Path dir1, Path dir2, boolean supportsLinks)251throws IOException252{253Path source, target, entry;254255boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));256257// -- regular file --258259/**260* Test: move regular file, target does not exist261*/262source = createSourceFile(dir1);263target = getTargetFile(dir2);264moveAndVerify(source, target);265delete(target);266267/**268* Test: move regular file, target exists269*/270source = createSourceFile(dir1);271target = getTargetFile(dir2);272createFile(target);273try {274moveAndVerify(source, target);275throw new RuntimeException("FileAlreadyExistsException expected");276} catch (FileAlreadyExistsException x) {277}278delete(target);279createDirectory(target);280try {281moveAndVerify(source, target);282throw new RuntimeException("FileAlreadyExistsException expected");283} catch (FileAlreadyExistsException x) {284}285delete(source);286delete(target);287288/**289* Test: move regular file, target does not exist290*/291source = createSourceFile(dir1);292target = getTargetFile(dir2);293moveAndVerify(source, target, REPLACE_EXISTING);294delete(target);295296/**297* Test: move regular file, target exists298*/299source = createSourceFile(dir1);300target = getTargetFile(dir2);301createFile(target);302moveAndVerify(source, target, REPLACE_EXISTING);303delete(target);304305/**306* Test: move regular file, target exists and is empty directory307*/308source = createSourceFile(dir1);309target = getTargetFile(dir2);310createDirectory(target);311moveAndVerify(source, target, REPLACE_EXISTING);312delete(target);313314/**315* Test: move regular file, target exists and is non-empty directory316*/317source = createSourceFile(dir1);318target = getTargetFile(dir2);319createDirectory(target);320entry = target.resolve("foo");321createFile(entry);322try {323moveAndVerify(source, target);324throw new RuntimeException("FileAlreadyExistsException expected");325} catch (FileAlreadyExistsException x) {326}327delete(entry);328delete(source);329delete(target);330331/**332* Test atomic move of regular file (same file store)333*/334source = createSourceFile(dir1);335target = getTargetFile(dir1);336moveAndVerify(source, target, ATOMIC_MOVE);337delete(target);338339/**340* Test atomic move of regular file (different file store)341*/342if (!sameDevice) {343source = createSourceFile(dir1);344target = getTargetFile(dir2);345try {346moveAndVerify(source, target, ATOMIC_MOVE);347throw new RuntimeException("AtomicMoveNotSupportedException expected");348} catch (AtomicMoveNotSupportedException x) {349}350delete(source);351}352353// -- directories --354355/*356* Test: move empty directory, target does not exist357*/358source = createSourceDirectory(dir1);359target = getTargetFile(dir2);360moveAndVerify(source, target);361delete(target);362363/**364* Test: move empty directory, target exists365*/366source = createSourceDirectory(dir1);367target = getTargetFile(dir2);368createFile(target);369try {370moveAndVerify(source, target);371throw new RuntimeException("FileAlreadyExistsException expected");372} catch (FileAlreadyExistsException x) {373}374delete(target);375createDirectory(target);376try {377moveAndVerify(source, target);378throw new RuntimeException("FileAlreadyExistsException expected");379} catch (FileAlreadyExistsException x) {380}381delete(source);382delete(target);383384/**385* Test: move empty directory, target does not exist386*/387source = createSourceDirectory(dir1);388target = getTargetFile(dir2);389moveAndVerify(source, target, REPLACE_EXISTING);390delete(target);391392/**393* Test: move empty directory, target exists394*/395source = createSourceDirectory(dir1);396target = getTargetFile(dir2);397createFile(target);398moveAndVerify(source, target, REPLACE_EXISTING);399delete(target);400401/**402* Test: move empty, target exists and is empty directory403*/404source = createSourceDirectory(dir1);405target = getTargetFile(dir2);406createDirectory(target);407moveAndVerify(source, target, REPLACE_EXISTING);408delete(target);409410/**411* Test: move empty directory, target exists and is non-empty directory412*/413source = createSourceDirectory(dir1);414target = getTargetFile(dir2);415createDirectory(target);416entry = target.resolve("foo");417createFile(entry);418try {419moveAndVerify(source, target, REPLACE_EXISTING);420throw new RuntimeException("DirectoryNotEmptyException expected");421} catch (DirectoryNotEmptyException x) {422}423delete(entry);424delete(source);425delete(target);426427/**428* Test: move non-empty directory (same file system)429*/430source = createSourceDirectory(dir1);431createFile(source.resolve("foo"));432target = getTargetFile(dir1);433moveAndVerify(source, target);434delete(target.resolve("foo"));435delete(target);436437/**438* Test: move non-empty directory (different file store)439*/440if (!sameDevice) {441source = createSourceDirectory(dir1);442createFile(source.resolve("foo"));443target = getTargetFile(dir2);444try {445moveAndVerify(source, target);446throw new RuntimeException("IOException expected");447} catch (IOException x) {448}449delete(source.resolve("foo"));450delete(source);451}452453/**454* Test atomic move of directory (same file store)455*/456source = createSourceDirectory(dir1);457createFile(source.resolve("foo"));458target = getTargetFile(dir1);459moveAndVerify(source, target, ATOMIC_MOVE);460delete(target.resolve("foo"));461delete(target);462463// -- symbolic links --464465/**466* Test: Move symbolic link to file, target does not exist467*/468if (supportsLinks) {469Path tmp = createSourceFile(dir1);470source = dir1.resolve("link");471createSymbolicLink(source, tmp);472target = getTargetFile(dir2);473moveAndVerify(source, target);474delete(target);475delete(tmp);476}477478/**479* Test: Move symbolic link to directory, target does not exist480*/481if (supportsLinks) {482source = dir1.resolve("link");483createSymbolicLink(source, dir2);484target = getTargetFile(dir2);485moveAndVerify(source, target);486delete(target);487}488489/**490* Test: Move broken symbolic link, target does not exists491*/492if (supportsLinks) {493Path tmp = Paths.get("doesnotexist");494source = dir1.resolve("link");495createSymbolicLink(source, tmp);496target = getTargetFile(dir2);497moveAndVerify(source, target);498delete(target);499}500501/**502* Test: Move symbolic link, target exists503*/504if (supportsLinks) {505source = dir1.resolve("link");506createSymbolicLink(source, dir2);507target = getTargetFile(dir2);508createFile(target);509try {510moveAndVerify(source, target);511throw new RuntimeException("FileAlreadyExistsException expected");512} catch (FileAlreadyExistsException x) {513}514delete(source);515delete(target);516}517518/**519* Test: Move regular file, target exists520*/521if (supportsLinks) {522source = dir1.resolve("link");523createSymbolicLink(source, dir2);524target = getTargetFile(dir2);525createFile(target);526moveAndVerify(source, target, REPLACE_EXISTING);527delete(target);528}529530/**531* Test: move symbolic link, target exists and is empty directory532*/533if (supportsLinks) {534source = dir1.resolve("link");535createSymbolicLink(source, dir2);536target = getTargetFile(dir2);537createDirectory(target);538moveAndVerify(source, target, REPLACE_EXISTING);539delete(target);540}541542/**543* Test: symbolic link, target exists and is non-empty directory544*/545if (supportsLinks) {546source = dir1.resolve("link");547createSymbolicLink(source, dir2);548target = getTargetFile(dir2);549createDirectory(target);550entry = target.resolve("foo");551createFile(entry);552try {553moveAndVerify(source, target);554throw new RuntimeException("FileAlreadyExistsException expected");555} catch (FileAlreadyExistsException x) {556}557delete(entry);558delete(source);559delete(target);560}561562/**563* Test atomic move of symbolic link (same file store)564*/565if (supportsLinks) {566source = dir1.resolve("link");567createSymbolicLink(source, dir1);568target = getTargetFile(dir2);569createFile(target);570moveAndVerify(source, target, REPLACE_EXISTING);571delete(target);572}573574// -- misc. tests --575576/**577* Test nulls578*/579source = createSourceFile(dir1);580target = getTargetFile(dir2);581try {582move(null, target);583throw new RuntimeException("NullPointerException expected");584} catch (NullPointerException x) { }585try {586move(source, null);587throw new RuntimeException("NullPointerException expected");588} catch (NullPointerException x) { }589try {590move(source, target, (CopyOption[])null);591throw new RuntimeException("NullPointerException expected");592} catch (NullPointerException x) { }593try {594CopyOption[] opts = { REPLACE_EXISTING, null };595move(source, target, opts);596throw new RuntimeException("NullPointerException expected");597} catch (NullPointerException x) { }598delete(source);599600/**601* Test UOE602*/603source = createSourceFile(dir1);604target = getTargetFile(dir2);605try {606move(source, target, new CopyOption() { });607} catch (UnsupportedOperationException x) { }608try {609move(source, target, REPLACE_EXISTING, new CopyOption() { });610} catch (UnsupportedOperationException x) { }611delete(source);612}613614// copy source to target with verification615static void copyAndVerify(Path source, Path target, CopyOption... options)616throws IOException617{618Path result = copy(source, target, options);619assertTrue(result == target);620621// get attributes of source and target file to verify copy622boolean followLinks = true;623LinkOption[] linkOptions = new LinkOption[0];624boolean copyAttributes = false;625for (CopyOption opt : options) {626if (opt == NOFOLLOW_LINKS) {627followLinks = false;628linkOptions = new LinkOption[] { NOFOLLOW_LINKS };629}630if (opt == COPY_ATTRIBUTES)631copyAttributes = true;632}633BasicFileAttributes basicAttributes =634readAttributes(source, BasicFileAttributes.class, linkOptions);635636// check hash if regular file637if (basicAttributes.isRegularFile())638assertTrue(computeHash(source) == computeHash(target));639640// check link target if symbolic link641if (basicAttributes.isSymbolicLink())642assert(readSymbolicLink(source).equals(readSymbolicLink(target)));643644// check that attributes are copied645if (copyAttributes && followLinks) {646checkBasicAttributes(basicAttributes,647readAttributes(source, BasicFileAttributes.class, linkOptions));648649// verify other attributes when same provider650if (source.getFileSystem().provider() == target.getFileSystem().provider()) {651652// check POSIX attributes are copied653String os = System.getProperty("os.name");654if ((os.equals("SunOS") || os.equals("Linux")) &&655testPosixAttributes)656{657checkPosixAttributes(658readAttributes(source, PosixFileAttributes.class, linkOptions),659readAttributes(target, PosixFileAttributes.class, linkOptions));660}661662// check DOS attributes are copied663if (os.startsWith("Windows")) {664checkDosAttributes(665readAttributes(source, DosFileAttributes.class, linkOptions),666readAttributes(target, DosFileAttributes.class, linkOptions));667}668669// check named attributes are copied670if (followLinks &&671getFileStore(source).supportsFileAttributeView("xattr") &&672getFileStore(target).supportsFileAttributeView("xattr"))673{674checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),675readUserDefinedFileAttributes(target));676}677}678}679}680681/**682* Tests all possible ways to invoke copy to copy a file to a file683*/684static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks)685throws IOException686{687Path source, target, link, entry;688689// -- regular file --690691/**692* Test: move regular file, target does not exist693*/694source = createSourceFile(dir1);695target = getTargetFile(dir2);696copyAndVerify(source, target);697delete(source);698delete(target);699700/**701* Test: copy regular file, target exists702*/703source = createSourceFile(dir1);704target = getTargetFile(dir2);705createFile(target);706try {707copyAndVerify(source, target);708throw new RuntimeException("FileAlreadyExistsException expected");709} catch (FileAlreadyExistsException x) {710}711delete(target);712createDirectory(target);713try {714copyAndVerify(source, target);715throw new RuntimeException("FileAlreadyExistsException expected");716} catch (FileAlreadyExistsException x) {717}718delete(source);719delete(target);720721/**722* Test: copy regular file, target does not exist723*/724source = createSourceFile(dir1);725target = getTargetFile(dir2);726copyAndVerify(source, target, REPLACE_EXISTING);727delete(source);728delete(target);729730/**731* Test: copy regular file, target exists732*/733source = createSourceFile(dir1);734target = getTargetFile(dir2);735createFile(target);736copyAndVerify(source, target, REPLACE_EXISTING);737delete(source);738delete(target);739740/**741* Test: copy regular file, target exists and is empty directory742*/743source = createSourceFile(dir1);744target = getTargetFile(dir2);745createDirectory(target);746copyAndVerify(source, target, REPLACE_EXISTING);747delete(source);748delete(target);749750/**751* Test: copy regular file, target exists and is non-empty directory752*/753source = createSourceFile(dir1);754target = getTargetFile(dir2);755createDirectory(target);756entry = target.resolve("foo");757createFile(entry);758try {759copyAndVerify(source, target);760throw new RuntimeException("FileAlreadyExistsException expected");761} catch (FileAlreadyExistsException x) {762}763delete(entry);764delete(source);765delete(target);766767/**768* Test: copy regular file + attributes769*/770source = createSourceFile(dir1);771target = getTargetFile(dir2);772copyAndVerify(source, target, COPY_ATTRIBUTES);773delete(source);774delete(target);775776777// -- directory --778779/*780* Test: copy directory, target does not exist781*/782source = createSourceDirectory(dir1);783target = getTargetFile(dir2);784copyAndVerify(source, target);785delete(source);786delete(target);787788/**789* Test: copy directory, target exists790*/791source = createSourceDirectory(dir1);792target = getTargetFile(dir2);793createFile(target);794try {795copyAndVerify(source, target);796throw new RuntimeException("FileAlreadyExistsException expected");797} catch (FileAlreadyExistsException x) {798}799delete(target);800createDirectory(target);801try {802copyAndVerify(source, target);803throw new RuntimeException("FileAlreadyExistsException expected");804} catch (FileAlreadyExistsException x) {805}806delete(source);807delete(target);808809/**810* Test: copy directory, target does not exist811*/812source = createSourceDirectory(dir1);813target = getTargetFile(dir2);814copyAndVerify(source, target, REPLACE_EXISTING);815delete(source);816delete(target);817818/**819* Test: copy directory, target exists820*/821source = createSourceDirectory(dir1);822target = getTargetFile(dir2);823createFile(target);824copyAndVerify(source, target, REPLACE_EXISTING);825delete(source);826delete(target);827828/**829* Test: copy directory, target exists and is empty directory830*/831source = createSourceDirectory(dir1);832target = getTargetFile(dir2);833createDirectory(target);834copyAndVerify(source, target, REPLACE_EXISTING);835delete(source);836delete(target);837838/**839* Test: copy directory, target exists and is non-empty directory840*/841source = createSourceDirectory(dir1);842target = getTargetFile(dir2);843createDirectory(target);844entry = target.resolve("foo");845createFile(entry);846try {847copyAndVerify(source, target, REPLACE_EXISTING);848throw new RuntimeException("DirectoryNotEmptyException expected");849} catch (DirectoryNotEmptyException x) {850}851delete(entry);852delete(source);853delete(target);854855/*856* Test: copy directory + attributes857*/858source = createSourceDirectory(dir1);859target = getTargetFile(dir2);860copyAndVerify(source, target, COPY_ATTRIBUTES);861delete(source);862delete(target);863864// -- symbolic links --865866/**867* Test: Follow link868*/869if (supportsLinks) {870source = createSourceFile(dir1);871link = dir1.resolve("link");872createSymbolicLink(link, source);873target = getTargetFile(dir2);874copyAndVerify(link, target);875delete(link);876delete(source);877}878879/**880* Test: Copy link (to file)881*/882if (supportsLinks) {883source = createSourceFile(dir1);884link = dir1.resolve("link");885createSymbolicLink(link, source);886target = getTargetFile(dir2);887copyAndVerify(link, target, NOFOLLOW_LINKS);888delete(link);889delete(source);890}891892/**893* Test: Copy link (to directory)894*/895if (supportsLinks) {896source = dir1.resolve("mydir");897createDirectory(source);898link = dir1.resolve("link");899createSymbolicLink(link, source);900target = getTargetFile(dir2);901copyAndVerify(link, target, NOFOLLOW_LINKS);902delete(link);903delete(source);904}905906/**907* Test: Copy broken link908*/909if (supportsLinks) {910assertTrue(notExists(source));911link = dir1.resolve("link");912createSymbolicLink(link, source);913target = getTargetFile(dir2);914copyAndVerify(link, target, NOFOLLOW_LINKS);915delete(link);916}917918/**919* Test: Copy link to UNC (Windows only)920*/921if (supportsLinks &&922System.getProperty("os.name").startsWith("Windows"))923{924Path unc = Paths.get("\\\\rialto\\share\\file");925link = dir1.resolve("link");926createSymbolicLink(link, unc);927target = getTargetFile(dir2);928copyAndVerify(link, target, NOFOLLOW_LINKS);929delete(link);930}931932// -- misc. tests --933934/**935* Test nulls936*/937source = createSourceFile(dir1);938target = getTargetFile(dir2);939try {940copy(source, null);941throw new RuntimeException("NullPointerException expected");942} catch (NullPointerException x) { }943try {944copy(source, target, (CopyOption[])null);945throw new RuntimeException("NullPointerException expected");946} catch (NullPointerException x) { }947try {948CopyOption[] opts = { REPLACE_EXISTING, null };949copy(source, target, opts);950throw new RuntimeException("NullPointerException expected");951} catch (NullPointerException x) { }952delete(source);953954/**955* Test UOE956*/957source = createSourceFile(dir1);958target = getTargetFile(dir2);959try {960copy(source, target, new CopyOption() { });961} catch (UnsupportedOperationException x) { }962try {963copy(source, target, REPLACE_EXISTING, new CopyOption() { });964} catch (UnsupportedOperationException x) { }965delete(source);966}967968/**969* Test copy from an input stream to a file970*/971static void testCopyInputStreamToFile() throws IOException {972testCopyInputStreamToFile(0);973for (int i=0; i<100; i++) {974testCopyInputStreamToFile(rand.nextInt(32000));975}976977// FileAlreadyExistsException978Path target = createTempFile("blah", null);979try {980InputStream in = new ByteArrayInputStream(new byte[0]);981try {982copy(in, target);983throw new RuntimeException("FileAlreadyExistsException expected");984} catch (FileAlreadyExistsException ignore) { }985} finally {986delete(target);987}988Path tmpdir = createTempDirectory("blah");989try {990if (TestUtil.supportsLinks(tmpdir)) {991Path link = createSymbolicLink(tmpdir.resolve("link"),992tmpdir.resolve("target"));993try {994InputStream in = new ByteArrayInputStream(new byte[0]);995try {996copy(in, link);997throw new RuntimeException("FileAlreadyExistsException expected");998} catch (FileAlreadyExistsException ignore) { }999} finally {1000delete(link);1001}1002}1003} finally {1004delete(tmpdir);1005}100610071008// nulls1009try {1010copy((InputStream)null, target);1011throw new RuntimeException("NullPointerException expected");1012} catch (NullPointerException ignore) { }1013try {1014copy(new ByteArrayInputStream(new byte[0]), (Path)null);1015throw new RuntimeException("NullPointerException expected");1016} catch (NullPointerException ignore) { }1017}10181019static void testCopyInputStreamToFile(int size) throws IOException {1020Path tmpdir = createTempDirectory("blah");1021Path source = tmpdir.resolve("source");1022Path target = tmpdir.resolve("target");1023try {1024boolean testReplaceExisting = rand.nextBoolean();10251026// create source file1027byte[] b = new byte[size];1028rand.nextBytes(b);1029write(source, b);10301031// target file might already exist1032if (testReplaceExisting && rand.nextBoolean()) {1033write(target, new byte[rand.nextInt(512)]);1034}10351036// copy from stream to file1037InputStream in = new FileInputStream(source.toFile());1038try {1039long n;1040if (testReplaceExisting) {1041n = copy(in, target, StandardCopyOption.REPLACE_EXISTING);1042} else {1043n = copy(in, target);1044}1045assertTrue(in.read() == -1); // EOF1046assertTrue(n == size);1047assertTrue(size(target) == size);1048} finally {1049in.close();1050}10511052// check file1053byte[] read = readAllBytes(target);1054assertTrue(Arrays.equals(read, b));10551056} finally {1057deleteIfExists(source);1058deleteIfExists(target);1059delete(tmpdir);1060}1061}10621063/**1064* Test copy from file to output stream1065*/1066static void testCopyFileToOuputStream() throws IOException {1067testCopyFileToOuputStream(0);1068for (int i=0; i<100; i++) {1069testCopyFileToOuputStream(rand.nextInt(32000));1070}10711072// nulls1073try {1074copy((Path)null, new ByteArrayOutputStream());1075throw new RuntimeException("NullPointerException expected");1076} catch (NullPointerException ignore) { }1077try {1078Path source = createTempFile("blah", null);1079delete(source);1080copy(source, (OutputStream)null);1081throw new RuntimeException("NullPointerException expected");1082} catch (NullPointerException ignore) { }1083}10841085static void testCopyFileToOuputStream(int size) throws IOException {1086Path source = createTempFile("blah", null);1087try {1088byte[] b = new byte[size];1089rand.nextBytes(b);1090write(source, b);10911092ByteArrayOutputStream out = new ByteArrayOutputStream();10931094long n = copy(source, out);1095assertTrue(n == size);1096assertTrue(out.size() == size);10971098byte[] read = out.toByteArray();1099assertTrue(Arrays.equals(read, b));11001101// check output stream is open1102out.write(0);1103assertTrue(out.size() == size+1);1104} finally {1105delete(source);1106}1107}11081109static void assertTrue(boolean value) {1110if (!value)1111throw new RuntimeException("Assertion failed");1112}11131114// computes simple hash of the given file1115static int computeHash(Path file) throws IOException {1116int h = 0;11171118try (InputStream in = newInputStream(file)) {1119byte[] buf = new byte[1024];1120int n;1121do {1122n = in.read(buf);1123for (int i=0; i<n; i++) {1124h = 31*h + (buf[i] & 0xff);1125}1126} while (n > 0);1127}1128return h;1129}11301131// create file of random size in given directory1132static Path createSourceFile(Path dir) throws IOException {1133String name = "source" + Integer.toString(rand.nextInt());1134Path file = dir.resolve(name);1135createFile(file);1136byte[] bytes = new byte[rand.nextInt(128*1024)];1137rand.nextBytes(bytes);1138try (OutputStream out = newOutputStream(file)) {1139out.write(bytes);1140}1141randomizeAttributes(file);1142return file;1143}11441145// create directory in the given directory1146static Path createSourceDirectory(Path dir) throws IOException {1147String name = "sourcedir" + Integer.toString(rand.nextInt());1148Path subdir = dir.resolve(name);1149createDirectory(subdir);1150randomizeAttributes(subdir);1151return subdir;1152}11531154// "randomize" the file attributes of the given file.1155static void randomizeAttributes(Path file) throws IOException {1156String os = System.getProperty("os.name");1157boolean isWindows = os.startsWith("Windows");1158boolean isUnix = os.equals("SunOS") || os.equals("Linux");1159boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);11601161if (isUnix) {1162Set<PosixFilePermission> perms =1163getPosixFilePermissions(file, NOFOLLOW_LINKS);1164PosixFilePermission[] toChange = {1165PosixFilePermission.GROUP_READ,1166PosixFilePermission.GROUP_WRITE,1167PosixFilePermission.GROUP_EXECUTE,1168PosixFilePermission.OTHERS_READ,1169PosixFilePermission.OTHERS_WRITE,1170PosixFilePermission.OTHERS_EXECUTE1171};1172for (PosixFilePermission perm: toChange) {1173if (heads()) {1174perms.add(perm);1175} else {1176perms.remove(perm);1177}1178}1179setPosixFilePermissions(file, perms);1180}11811182if (isWindows) {1183DosFileAttributeView view =1184getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);1185// only set or unset the hidden attribute1186view.setHidden(heads());1187}11881189boolean addUserDefinedFileAttributes = heads() &&1190getFileStore(file).supportsFileAttributeView("xattr");11911192// remove this when copying a direcory copies its named streams1193if (isWindows && isDirectory) addUserDefinedFileAttributes = false;11941195if (addUserDefinedFileAttributes) {1196UserDefinedFileAttributeView view =1197getFileAttributeView(file, UserDefinedFileAttributeView.class);1198int n = rand.nextInt(16);1199while (n > 0) {1200byte[] value = new byte[1 + rand.nextInt(100)];1201view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));1202n--;1203}1204}1205}12061207// create name for file in given directory1208static Path getTargetFile(Path dir) throws IOException {1209String name = "target" + Integer.toString(rand.nextInt());1210return dir.resolve(name);1211}1212}121312141215