Path: blob/master/test/jdk/java/nio/file/Files/CopyAndMove.java
41153 views
/*1* Copyright (c) 2008, 2018, 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 8006645 820140725* @summary Unit test for java.nio.file.Files copy and move methods (use -Dseed=X to set PRNG seed)26* @library .. /test/lib27* @build jdk.test.lib.Platform jdk.test.lib.RandomFactory28* CopyAndMove PassThroughFileSystem29* @run main/othervm CopyAndMove30* @key randomness31*/3233import java.io.*;34import java.nio.ByteBuffer;35import java.nio.file.*;36import static java.nio.file.Files.*;37import static java.nio.file.StandardCopyOption.*;38import static java.nio.file.LinkOption.*;39import java.nio.file.attribute.*;40import java.util.*;41import java.util.concurrent.TimeUnit;42import jdk.test.lib.Platform;43import jdk.test.lib.RandomFactory;4445public class CopyAndMove {46static final Random rand = RandomFactory.getRandom();47static boolean heads() { return rand.nextBoolean(); }48private static boolean testPosixAttributes = false;4950public static void main(String[] args) throws Exception {51Path dir1 = TestUtil.createTemporaryDirectory();52try {5354// Same directory55FileStore fileStore1 = getFileStore(dir1);56printDirInfo("dir1", dir1, fileStore1);57testPosixAttributes = fileStore1.supportsFileAttributeView("posix");58testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));59testMove(dir1, dir1, TestUtil.supportsLinks(dir1));6061// Different directories. Use test.dir if possible as it might be62// a different volume/file system and so improve test coverage.63String testDir = System.getProperty("test.dir", ".");64Path dir2 = TestUtil.createTemporaryDirectory(testDir);65try {66boolean testSymbolicLinks =67TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);68FileStore fileStore2 = getFileStore(dir2);69printDirInfo("dir2", dir2, fileStore2);70testPosixAttributes = fileStore1.supportsFileAttributeView("posix") &&71fileStore2.supportsFileAttributeView("posix");72testCopyFileToFile(dir1, dir2, testSymbolicLinks);73testMove(dir1, dir2, testSymbolicLinks);74} finally {75TestUtil.removeAll(dir2);76}7778// Target is location associated with custom provider79Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());80FileStore fileStore3 = getFileStore(dir3);81printDirInfo("dir3", dir3, fileStore3);82testPosixAttributes = fileStore1.supportsFileAttributeView("posix") &&83fileStore3.supportsFileAttributeView("posix");84testCopyFileToFile(dir1, dir3, false);85testMove(dir1, dir3, false);8687// Test copy(InputStream,Path) and copy(Path,OutputStream)88testCopyInputStreamToFile();89testCopyFileToOuputStream();9091} finally {92TestUtil.removeAll(dir1);93}94}9596static void printDirInfo(String name, Path dir, FileStore store)97throws IOException {98System.err.format("%s: %s (%s)%n", name, dir, store.type());99}100101static void checkBasicAttributes(BasicFileAttributes attrs1,102BasicFileAttributes attrs2)103{104// check file type105assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());106assertTrue(attrs1.isDirectory() == attrs2.isDirectory());107assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());108assertTrue(attrs1.isOther() == attrs2.isOther());109110// check last modified time if not a symbolic link111if (!attrs1.isSymbolicLink()) {112long time1 = attrs1.lastModifiedTime().to(TimeUnit.SECONDS);113long time2 = attrs2.lastModifiedTime().to(TimeUnit.SECONDS);114115if (time1 != time2) {116System.err.format("File time for %s is %s\n", attrs1.fileKey(), attrs1.lastModifiedTime());117System.err.format("File time for %s is %s\n", attrs2.fileKey(), attrs2.lastModifiedTime());118assertTrue(false);119}120}121122// check size123if (attrs1.isRegularFile())124assertTrue(attrs1.size() == attrs2.size());125}126127static void checkPosixAttributes(PosixFileAttributes attrs1,128PosixFileAttributes attrs2)129{130assertTrue(attrs1.permissions().equals(attrs2.permissions()),131"permissions%n1 (%d): %s%n2 (%d): %s%n%n",132attrs1.permissions().size(), attrs1.permissions(),133attrs2.permissions().size(), attrs2.permissions());134assertTrue(attrs1.owner().equals(attrs2.owner()),135"owner%n1: %s%n2: %s%n%n", attrs1.owner(), attrs2.owner());136assertTrue(attrs1.group().equals(attrs2.group()),137"group%n1: %s%n2: %s%n%n", attrs1.group(), attrs2.group());138}139140static void checkDosAttributes(DosFileAttributes attrs1,141DosFileAttributes attrs2)142{143assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly(),144"isReadOnly%n1: %s%n2: %s%n%n", attrs1.isReadOnly(), attrs2.isReadOnly());145assertTrue(attrs1.isHidden() == attrs2.isHidden(),146"isHidden%n1: %s%n2: %s%n%n", attrs1.isHidden(), attrs2.isHidden());147assertTrue(attrs1.isSystem() == attrs2.isSystem(),148"isSystem%n1: %s%n2: %s%n%n", attrs1.isSystem(), attrs2.isSystem());149}150151static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,152Map<String,ByteBuffer> attrs2)153{154assert attrs1.size() == attrs2.size();155for (String name: attrs1.keySet()) {156ByteBuffer bb1 = attrs1.get(name);157ByteBuffer bb2 = attrs2.get(name);158assertTrue(bb2 != null);159assertTrue(bb1.equals(bb2));160}161}162163static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)164throws IOException165{166UserDefinedFileAttributeView view =167getFileAttributeView(file, UserDefinedFileAttributeView.class);168Map<String,ByteBuffer> result = new HashMap<>();169for (String name: view.list()) {170int size = view.size(name);171ByteBuffer bb = ByteBuffer.allocate(size);172int n = view.read(name, bb);173assertTrue(n == size);174bb.flip();175result.put(name, bb);176}177return result;178}179180// move source to target with verification181static void moveAndVerify(Path source, Path target, CopyOption... options)182throws IOException183{184// read attributes before file is moved185BasicFileAttributes basicAttributes = null;186PosixFileAttributes posixAttributes = null;187DosFileAttributes dosAttributes = null;188Map<String,ByteBuffer> namedAttributes = null;189190// get file attributes of source file191if (Platform.isWindows()) {192dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);193basicAttributes = dosAttributes;194} else {195posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);196basicAttributes = posixAttributes;197}198if (basicAttributes == null)199basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);200201// hash file contents if regular file202int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;203204// record link target if symbolic link205Path linkTarget = null;206if (basicAttributes.isSymbolicLink())207linkTarget = readSymbolicLink(source);208209// read named attributes if available (and file is not a sym link)210if (!basicAttributes.isSymbolicLink() &&211getFileStore(source).supportsFileAttributeView("xattr"))212{213namedAttributes = readUserDefinedFileAttributes(source);214}215216// move file217Path result = move(source, target, options);218assertTrue(result == target);219220// verify source does not exist221assertTrue(notExists(source));222223// verify file contents224if (basicAttributes.isRegularFile()) {225if (computeHash(target) != hash)226throw new RuntimeException("Failed to verify move of regular file");227}228229// verify link target230if (basicAttributes.isSymbolicLink()) {231if (!readSymbolicLink(target).equals(linkTarget))232throw new RuntimeException("Failed to verify move of symbolic link");233}234235// verify basic attributes236checkBasicAttributes(basicAttributes,237readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));238239// verify other attributes when same provider240if (source.getFileSystem().provider() == target.getFileSystem().provider()) {241242// verify POSIX attributes243if (posixAttributes != null &&244!basicAttributes.isSymbolicLink() &&245testPosixAttributes)246{247checkPosixAttributes(posixAttributes,248readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));249}250251// verify DOS attributes252if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {253DosFileAttributes attrs =254readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);255checkDosAttributes(dosAttributes, attrs);256}257258// verify named attributes259if (namedAttributes != null &&260getFileStore(target).supportsFileAttributeView("xattr"))261{262checkUserDefinedFileAttributes(namedAttributes,263readUserDefinedFileAttributes(target));264}265}266}267268/**269* Tests all possible ways to invoke move270*/271static void testMove(Path dir1, Path dir2, boolean supportsLinks)272throws IOException273{274Path source, target, entry;275276boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));277278// -- regular file --279280/**281* Test: move regular file, target does not exist282*/283source = createSourceFile(dir1);284target = getTargetFile(dir2);285moveAndVerify(source, target);286delete(target);287288/**289* Test: move regular file, target exists290*/291source = createSourceFile(dir1);292target = getTargetFile(dir2);293createFile(target);294try {295moveAndVerify(source, target);296throw new RuntimeException("FileAlreadyExistsException expected");297} catch (FileAlreadyExistsException x) {298}299delete(target);300createDirectory(target);301try {302moveAndVerify(source, target);303throw new RuntimeException("FileAlreadyExistsException expected");304} catch (FileAlreadyExistsException x) {305}306delete(source);307delete(target);308309/**310* Test: move regular file, target does not exist311*/312source = createSourceFile(dir1);313target = getTargetFile(dir2);314moveAndVerify(source, target, REPLACE_EXISTING);315delete(target);316317/**318* Test: move regular file, target exists319*/320source = createSourceFile(dir1);321target = getTargetFile(dir2);322createFile(target);323moveAndVerify(source, target, REPLACE_EXISTING);324delete(target);325326/**327* Test: move regular file, target exists and is empty directory328*/329source = createSourceFile(dir1);330target = getTargetFile(dir2);331createDirectory(target);332moveAndVerify(source, target, REPLACE_EXISTING);333delete(target);334335/**336* Test: move regular file, target exists and is non-empty directory337*/338source = createSourceFile(dir1);339target = getTargetFile(dir2);340createDirectory(target);341entry = target.resolve("foo");342createFile(entry);343try {344moveAndVerify(source, target);345throw new RuntimeException("FileAlreadyExistsException expected");346} catch (FileAlreadyExistsException x) {347}348delete(entry);349delete(source);350delete(target);351352/**353* Test atomic move of regular file (same file store)354*/355source = createSourceFile(dir1);356target = getTargetFile(dir1);357moveAndVerify(source, target, ATOMIC_MOVE);358delete(target);359360/**361* Test atomic move of regular file (different file store)362*/363if (!sameDevice) {364source = createSourceFile(dir1);365target = getTargetFile(dir2);366try {367moveAndVerify(source, target, ATOMIC_MOVE);368throw new RuntimeException("AtomicMoveNotSupportedException expected");369} catch (AtomicMoveNotSupportedException x) {370}371delete(source);372}373374// -- directories --375376/*377* Test: move empty directory, target does not exist378*/379source = createSourceDirectory(dir1);380target = getTargetFile(dir2);381moveAndVerify(source, target);382delete(target);383384/**385* Test: move empty directory, target exists386*/387source = createSourceDirectory(dir1);388target = getTargetFile(dir2);389createFile(target);390try {391moveAndVerify(source, target);392throw new RuntimeException("FileAlreadyExistsException expected");393} catch (FileAlreadyExistsException x) {394}395delete(target);396createDirectory(target);397try {398moveAndVerify(source, target);399throw new RuntimeException("FileAlreadyExistsException expected");400} catch (FileAlreadyExistsException x) {401}402delete(source);403delete(target);404405/**406* Test: move empty directory, target does not exist407*/408source = createSourceDirectory(dir1);409target = getTargetFile(dir2);410moveAndVerify(source, target, REPLACE_EXISTING);411delete(target);412413/**414* Test: move empty directory, target exists415*/416source = createSourceDirectory(dir1);417target = getTargetFile(dir2);418createFile(target);419moveAndVerify(source, target, REPLACE_EXISTING);420delete(target);421422/**423* Test: move empty, target exists and is empty directory424*/425source = createSourceDirectory(dir1);426target = getTargetFile(dir2);427createDirectory(target);428moveAndVerify(source, target, REPLACE_EXISTING);429delete(target);430431/**432* Test: move empty directory, target exists and is non-empty directory433*/434source = createSourceDirectory(dir1);435target = getTargetFile(dir2);436createDirectory(target);437entry = target.resolve("foo");438createFile(entry);439try {440moveAndVerify(source, target, REPLACE_EXISTING);441throw new RuntimeException("DirectoryNotEmptyException expected");442} catch (DirectoryNotEmptyException x) {443}444delete(entry);445delete(source);446delete(target);447448/**449* Test: move non-empty directory (same file system)450*/451source = createSourceDirectory(dir1);452createFile(source.resolve("foo"));453target = getTargetFile(dir1);454moveAndVerify(source, target);455delete(target.resolve("foo"));456delete(target);457458/**459* Test: move non-empty directory (different file store)460*/461if (!sameDevice) {462source = createSourceDirectory(dir1);463createFile(source.resolve("foo"));464target = getTargetFile(dir2);465try {466moveAndVerify(source, target);467throw new RuntimeException("IOException expected");468} catch (IOException x) {469if (!(x instanceof DirectoryNotEmptyException)) {470throw new RuntimeException471("DirectoryNotEmptyException expected", x);472}473}474delete(source.resolve("foo"));475delete(source);476}477478/**479* Test atomic move of directory (same file store)480*/481source = createSourceDirectory(dir1);482createFile(source.resolve("foo"));483target = getTargetFile(dir1);484moveAndVerify(source, target, ATOMIC_MOVE);485delete(target.resolve("foo"));486delete(target);487488// -- symbolic links --489490/**491* Test: Move symbolic link to file, target does not exist492*/493if (supportsLinks) {494Path tmp = createSourceFile(dir1);495source = dir1.resolve("link");496createSymbolicLink(source, tmp);497target = getTargetFile(dir2);498moveAndVerify(source, target);499delete(target);500delete(tmp);501}502503/**504* Test: Move symbolic link to directory, target does not exist505*/506if (supportsLinks) {507source = dir1.resolve("link");508createSymbolicLink(source, dir2);509target = getTargetFile(dir2);510moveAndVerify(source, target);511delete(target);512}513514/**515* Test: Move broken symbolic link, target does not exists516*/517if (supportsLinks) {518Path tmp = Paths.get("doesnotexist");519source = dir1.resolve("link");520createSymbolicLink(source, tmp);521target = getTargetFile(dir2);522moveAndVerify(source, target);523delete(target);524}525526/**527* Test: Move symbolic link, target exists528*/529if (supportsLinks) {530source = dir1.resolve("link");531createSymbolicLink(source, dir2);532target = getTargetFile(dir2);533createFile(target);534try {535moveAndVerify(source, target);536throw new RuntimeException("FileAlreadyExistsException expected");537} catch (FileAlreadyExistsException x) {538}539delete(source);540delete(target);541}542543/**544* Test: Move regular file, target exists545*/546if (supportsLinks) {547source = dir1.resolve("link");548createSymbolicLink(source, dir2);549target = getTargetFile(dir2);550createFile(target);551moveAndVerify(source, target, REPLACE_EXISTING);552delete(target);553}554555/**556* Test: move symbolic link, target exists and is empty directory557*/558if (supportsLinks) {559source = dir1.resolve("link");560createSymbolicLink(source, dir2);561target = getTargetFile(dir2);562createDirectory(target);563moveAndVerify(source, target, REPLACE_EXISTING);564delete(target);565}566567/**568* Test: symbolic link, target exists and is non-empty directory569*/570if (supportsLinks) {571source = dir1.resolve("link");572createSymbolicLink(source, dir2);573target = getTargetFile(dir2);574createDirectory(target);575entry = target.resolve("foo");576createFile(entry);577try {578moveAndVerify(source, target);579throw new RuntimeException("FileAlreadyExistsException expected");580} catch (FileAlreadyExistsException x) {581}582delete(entry);583delete(source);584delete(target);585}586587/**588* Test atomic move of symbolic link (same file store)589*/590if (supportsLinks) {591source = dir1.resolve("link");592createSymbolicLink(source, dir1);593target = getTargetFile(dir2);594createFile(target);595moveAndVerify(source, target, REPLACE_EXISTING);596delete(target);597}598599// -- misc. tests --600601/**602* Test nulls603*/604source = createSourceFile(dir1);605target = getTargetFile(dir2);606try {607move(null, target);608throw new RuntimeException("NullPointerException expected");609} catch (NullPointerException x) { }610try {611move(source, null);612throw new RuntimeException("NullPointerException expected");613} catch (NullPointerException x) { }614try {615move(source, target, (CopyOption[])null);616throw new RuntimeException("NullPointerException expected");617} catch (NullPointerException x) { }618try {619CopyOption[] opts = { REPLACE_EXISTING, null };620move(source, target, opts);621throw new RuntimeException("NullPointerException expected");622} catch (NullPointerException x) { }623delete(source);624625/**626* Test UOE627*/628source = createSourceFile(dir1);629target = getTargetFile(dir2);630try {631move(source, target, new CopyOption() { });632} catch (UnsupportedOperationException x) { }633try {634move(source, target, REPLACE_EXISTING, new CopyOption() { });635} catch (UnsupportedOperationException x) { }636delete(source);637}638639// copy source to target with verification640static void copyAndVerify(Path source, Path target, CopyOption... options)641throws IOException642{643Path result = copy(source, target, options);644assertTrue(result == target);645646// get attributes of source and target file to verify copy647boolean followLinks = true;648LinkOption[] linkOptions = new LinkOption[0];649boolean copyAttributes = false;650for (CopyOption opt : options) {651if (opt == NOFOLLOW_LINKS) {652followLinks = false;653linkOptions = new LinkOption[] { NOFOLLOW_LINKS };654}655if (opt == COPY_ATTRIBUTES)656copyAttributes = true;657}658BasicFileAttributes basicAttributes =659readAttributes(source, BasicFileAttributes.class, linkOptions);660661// check hash if regular file662if (basicAttributes.isRegularFile())663assertTrue(computeHash(source) == computeHash(target));664665// check link target if symbolic link666if (basicAttributes.isSymbolicLink())667assert(readSymbolicLink(source).equals(readSymbolicLink(target)));668669// check that attributes are copied670if (copyAttributes && followLinks) {671checkBasicAttributes(basicAttributes,672readAttributes(source, BasicFileAttributes.class, linkOptions));673674// verify other attributes when same provider675if (source.getFileSystem().provider() == target.getFileSystem().provider()) {676677// check POSIX attributes are copied678if (!Platform.isWindows() && testPosixAttributes) {679checkPosixAttributes(680readAttributes(source, PosixFileAttributes.class, linkOptions),681readAttributes(target, PosixFileAttributes.class, linkOptions));682}683684// check DOS attributes are copied685if (Platform.isWindows()) {686checkDosAttributes(687readAttributes(source, DosFileAttributes.class, linkOptions),688readAttributes(target, DosFileAttributes.class, linkOptions));689}690691// check named attributes are copied692if (followLinks &&693getFileStore(source).supportsFileAttributeView("xattr") &&694getFileStore(target).supportsFileAttributeView("xattr"))695{696checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),697readUserDefinedFileAttributes(target));698}699}700}701}702703/**704* Tests all possible ways to invoke copy to copy a file to a file705*/706static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks)707throws IOException708{709Path source, target, link, entry;710711// -- regular file --712713/**714* Test: move regular file, target does not exist715*/716source = createSourceFile(dir1);717target = getTargetFile(dir2);718copyAndVerify(source, target);719delete(source);720delete(target);721722/**723* Test: copy regular file, target exists724*/725source = createSourceFile(dir1);726target = getTargetFile(dir2);727createFile(target);728try {729copyAndVerify(source, target);730throw new RuntimeException("FileAlreadyExistsException expected");731} catch (FileAlreadyExistsException x) {732}733delete(target);734createDirectory(target);735try {736copyAndVerify(source, target);737throw new RuntimeException("FileAlreadyExistsException expected");738} catch (FileAlreadyExistsException x) {739}740delete(source);741delete(target);742743/**744* Test: copy regular file, target does not exist745*/746source = createSourceFile(dir1);747target = getTargetFile(dir2);748copyAndVerify(source, target, REPLACE_EXISTING);749delete(source);750delete(target);751752/**753* Test: copy regular file, target exists754*/755source = createSourceFile(dir1);756target = getTargetFile(dir2);757createFile(target);758copyAndVerify(source, target, REPLACE_EXISTING);759delete(source);760delete(target);761762/**763* Test: copy regular file, target exists and is empty directory764*/765source = createSourceFile(dir1);766target = getTargetFile(dir2);767createDirectory(target);768copyAndVerify(source, target, REPLACE_EXISTING);769delete(source);770delete(target);771772/**773* Test: copy regular file, target exists and is non-empty directory774*/775source = createSourceFile(dir1);776target = getTargetFile(dir2);777createDirectory(target);778entry = target.resolve("foo");779createFile(entry);780try {781copyAndVerify(source, target);782throw new RuntimeException("FileAlreadyExistsException expected");783} catch (FileAlreadyExistsException x) {784}785delete(entry);786delete(source);787delete(target);788789/**790* Test: copy regular file + attributes791*/792source = createSourceFile(dir1);793target = getTargetFile(dir2);794copyAndVerify(source, target, COPY_ATTRIBUTES);795delete(source);796delete(target);797798799// -- directory --800801/*802* Test: copy directory, target does not exist803*/804source = createSourceDirectory(dir1);805target = getTargetFile(dir2);806copyAndVerify(source, target);807delete(source);808delete(target);809810/**811* Test: copy directory, target exists812*/813source = createSourceDirectory(dir1);814target = getTargetFile(dir2);815createFile(target);816try {817copyAndVerify(source, target);818throw new RuntimeException("FileAlreadyExistsException expected");819} catch (FileAlreadyExistsException x) {820}821delete(target);822createDirectory(target);823try {824copyAndVerify(source, target);825throw new RuntimeException("FileAlreadyExistsException expected");826} catch (FileAlreadyExistsException x) {827}828delete(source);829delete(target);830831/**832* Test: copy directory, target does not exist833*/834source = createSourceDirectory(dir1);835target = getTargetFile(dir2);836copyAndVerify(source, target, REPLACE_EXISTING);837delete(source);838delete(target);839840/**841* Test: copy directory, target exists842*/843source = createSourceDirectory(dir1);844target = getTargetFile(dir2);845createFile(target);846copyAndVerify(source, target, REPLACE_EXISTING);847delete(source);848delete(target);849850/**851* Test: copy directory, target exists and is empty directory852*/853source = createSourceDirectory(dir1);854target = getTargetFile(dir2);855createDirectory(target);856copyAndVerify(source, target, REPLACE_EXISTING);857delete(source);858delete(target);859860/**861* Test: copy directory, target exists and is non-empty directory862*/863source = createSourceDirectory(dir1);864target = getTargetFile(dir2);865createDirectory(target);866entry = target.resolve("foo");867createFile(entry);868try {869copyAndVerify(source, target, REPLACE_EXISTING);870throw new RuntimeException("DirectoryNotEmptyException expected");871} catch (DirectoryNotEmptyException x) {872}873delete(entry);874delete(source);875delete(target);876877/*878* Test: copy directory + attributes879*/880source = createSourceDirectory(dir1);881target = getTargetFile(dir2);882copyAndVerify(source, target, COPY_ATTRIBUTES);883delete(source);884delete(target);885886// -- symbolic links --887888/**889* Test: Follow link890*/891if (supportsLinks) {892source = createSourceFile(dir1);893link = dir1.resolve("link");894createSymbolicLink(link, source);895target = getTargetFile(dir2);896copyAndVerify(link, target);897delete(link);898delete(source);899}900901/**902* Test: Copy link (to file)903*/904if (supportsLinks) {905source = createSourceFile(dir1);906link = dir1.resolve("link");907createSymbolicLink(link, source);908target = getTargetFile(dir2);909copyAndVerify(link, target, NOFOLLOW_LINKS);910delete(link);911delete(source);912}913914/**915* Test: Copy link (to directory)916*/917if (supportsLinks) {918source = dir1.resolve("mydir");919createDirectory(source);920link = dir1.resolve("link");921createSymbolicLink(link, source);922target = getTargetFile(dir2);923copyAndVerify(link, target, NOFOLLOW_LINKS);924delete(link);925delete(source);926}927928/**929* Test: Copy broken link930*/931if (supportsLinks) {932assertTrue(notExists(source));933link = dir1.resolve("link");934createSymbolicLink(link, source);935target = getTargetFile(dir2);936copyAndVerify(link, target, NOFOLLOW_LINKS);937delete(link);938}939940/**941* Test: Copy link to UNC (Windows only)942*/943if (supportsLinks && Platform.isWindows()) {944Path unc = Paths.get("\\\\rialto\\share\\file");945link = dir1.resolve("link");946createSymbolicLink(link, unc);947target = getTargetFile(dir2);948copyAndVerify(link, target, NOFOLLOW_LINKS);949delete(link);950}951952// -- misc. tests --953954/**955* Test nulls956*/957source = createSourceFile(dir1);958target = getTargetFile(dir2);959try {960copy(source, null);961throw new RuntimeException("NullPointerException expected");962} catch (NullPointerException x) { }963try {964copy(source, target, (CopyOption[])null);965throw new RuntimeException("NullPointerException expected");966} catch (NullPointerException x) { }967try {968CopyOption[] opts = { REPLACE_EXISTING, null };969copy(source, target, opts);970throw new RuntimeException("NullPointerException expected");971} catch (NullPointerException x) { }972delete(source);973974/**975* Test UOE976*/977source = createSourceFile(dir1);978target = getTargetFile(dir2);979try {980copy(source, target, new CopyOption() { });981} catch (UnsupportedOperationException x) { }982try {983copy(source, target, REPLACE_EXISTING, new CopyOption() { });984} catch (UnsupportedOperationException x) { }985delete(source);986}987988/**989* Test copy from an input stream to a file990*/991static void testCopyInputStreamToFile() throws IOException {992testCopyInputStreamToFile(0);993for (int i=0; i<100; i++) {994testCopyInputStreamToFile(rand.nextInt(32000));995}996997// FileAlreadyExistsException998Path target = createTempFile("blah", null);999try {1000InputStream in = new ByteArrayInputStream(new byte[0]);1001try {1002copy(in, target);1003throw new RuntimeException("FileAlreadyExistsException expected");1004} catch (FileAlreadyExistsException ignore) { }1005} finally {1006delete(target);1007}1008Path tmpdir = createTempDirectory("blah");1009try {1010if (TestUtil.supportsLinks(tmpdir)) {1011Path link = createSymbolicLink(tmpdir.resolve("link"),1012tmpdir.resolve("target"));1013try {1014InputStream in = new ByteArrayInputStream(new byte[0]);1015try {1016copy(in, link);1017throw new RuntimeException("FileAlreadyExistsException expected");1018} catch (FileAlreadyExistsException ignore) { }1019} finally {1020delete(link);1021}1022}1023} finally {1024delete(tmpdir);1025}102610271028// nulls1029try {1030copy((InputStream)null, target);1031throw new RuntimeException("NullPointerException expected");1032} catch (NullPointerException ignore) { }1033try {1034copy(new ByteArrayInputStream(new byte[0]), (Path)null);1035throw new RuntimeException("NullPointerException expected");1036} catch (NullPointerException ignore) { }1037}10381039static void testCopyInputStreamToFile(int size) throws IOException {1040Path tmpdir = createTempDirectory("blah");1041Path source = tmpdir.resolve("source");1042Path target = tmpdir.resolve("target");1043try {1044boolean testReplaceExisting = rand.nextBoolean();10451046// create source file1047byte[] b = new byte[size];1048rand.nextBytes(b);1049write(source, b);10501051// target file might already exist1052if (testReplaceExisting && rand.nextBoolean()) {1053write(target, new byte[rand.nextInt(512)]);1054}10551056// copy from stream to file1057InputStream in = new FileInputStream(source.toFile());1058try {1059long n;1060if (testReplaceExisting) {1061n = copy(in, target, StandardCopyOption.REPLACE_EXISTING);1062} else {1063n = copy(in, target);1064}1065assertTrue(in.read() == -1); // EOF1066assertTrue(n == size);1067assertTrue(size(target) == size);1068} finally {1069in.close();1070}10711072// check file1073byte[] read = readAllBytes(target);1074assertTrue(Arrays.equals(read, b));10751076} finally {1077deleteIfExists(source);1078deleteIfExists(target);1079delete(tmpdir);1080}1081}10821083/**1084* Test copy from file to output stream1085*/1086static void testCopyFileToOuputStream() throws IOException {1087testCopyFileToOuputStream(0);1088for (int i=0; i<100; i++) {1089testCopyFileToOuputStream(rand.nextInt(32000));1090}10911092// nulls1093try {1094copy((Path)null, new ByteArrayOutputStream());1095throw new RuntimeException("NullPointerException expected");1096} catch (NullPointerException ignore) { }1097try {1098Path source = createTempFile("blah", null);1099delete(source);1100copy(source, (OutputStream)null);1101throw new RuntimeException("NullPointerException expected");1102} catch (NullPointerException ignore) { }1103}11041105static void testCopyFileToOuputStream(int size) throws IOException {1106Path source = createTempFile("blah", null);1107try {1108byte[] b = new byte[size];1109rand.nextBytes(b);1110write(source, b);11111112ByteArrayOutputStream out = new ByteArrayOutputStream();11131114long n = copy(source, out);1115assertTrue(n == size);1116assertTrue(out.size() == size);11171118byte[] read = out.toByteArray();1119assertTrue(Arrays.equals(read, b));11201121// check output stream is open1122out.write(0);1123assertTrue(out.size() == size+1);1124} finally {1125delete(source);1126}1127}11281129static void assertTrue(boolean value) {1130if (!value)1131throw new RuntimeException("Assertion failed");1132}11331134static void assertTrue(boolean value, String format, Object... args) {1135if (!value) {1136System.err.format(format, args);1137throw new RuntimeException("Assertion failed");1138}1139}11401141// computes simple hash of the given file1142static int computeHash(Path file) throws IOException {1143int h = 0;11441145try (InputStream in = newInputStream(file)) {1146byte[] buf = new byte[1024];1147int n;1148do {1149n = in.read(buf);1150for (int i=0; i<n; i++) {1151h = 31*h + (buf[i] & 0xff);1152}1153} while (n > 0);1154}1155return h;1156}11571158// create file of random size in given directory1159static Path createSourceFile(Path dir) throws IOException {1160String name = "source" + Integer.toString(rand.nextInt());1161Path file = dir.resolve(name);1162createFile(file);1163byte[] bytes = new byte[rand.nextInt(128*1024)];1164rand.nextBytes(bytes);1165try (OutputStream out = newOutputStream(file)) {1166out.write(bytes);1167}1168randomizeAttributes(file);1169return file;1170}11711172// create directory in the given directory1173static Path createSourceDirectory(Path dir) throws IOException {1174String name = "sourcedir" + Integer.toString(rand.nextInt());1175Path subdir = dir.resolve(name);1176createDirectory(subdir);1177randomizeAttributes(subdir);1178return subdir;1179}11801181// "randomize" the file attributes of the given file.1182static void randomizeAttributes(Path file) throws IOException {1183boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);11841185if (Platform.isWindows()) {1186DosFileAttributeView view =1187getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);1188// only set or unset the hidden attribute1189view.setHidden(heads());1190} else {1191Set<PosixFilePermission> perms =1192getPosixFilePermissions(file, NOFOLLOW_LINKS);1193PosixFilePermission[] toChange = {1194PosixFilePermission.GROUP_READ,1195PosixFilePermission.GROUP_WRITE,1196PosixFilePermission.GROUP_EXECUTE,1197PosixFilePermission.OTHERS_READ,1198PosixFilePermission.OTHERS_WRITE,1199PosixFilePermission.OTHERS_EXECUTE1200};1201for (PosixFilePermission perm: toChange) {1202if (heads()) {1203perms.add(perm);1204} else {1205perms.remove(perm);1206}1207}1208setPosixFilePermissions(file, perms);1209}12101211boolean addUserDefinedFileAttributes = heads() &&1212getFileStore(file).supportsFileAttributeView("xattr");12131214// remove this when copying a direcory copies its named streams1215if (Platform.isWindows() && isDirectory)1216addUserDefinedFileAttributes = false;12171218if (addUserDefinedFileAttributes) {1219UserDefinedFileAttributeView view =1220getFileAttributeView(file, UserDefinedFileAttributeView.class);1221int n = rand.nextInt(16);1222while (n > 0) {1223byte[] value = new byte[1 + rand.nextInt(100)];1224view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));1225n--;1226}1227}1228}12291230// create name for file in given directory1231static Path getTargetFile(Path dir) throws IOException {1232String name = "target" + Integer.toString(rand.nextInt());1233return dir.resolve(name);1234}1235}123612371238