Skip to content

Commit

Permalink
delete#mustExist createDirectory#mustCreate
Browse files Browse the repository at this point in the history
  • Loading branch information
oldergod committed Oct 28, 2021
1 parent 6565389 commit ad1c093
Show file tree
Hide file tree
Showing 17 changed files with 272 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ class FakeFileSystem(
)
}

override fun createDirectory(dir: Path) {
override fun createDirectory(dir: Path, mustCreate: Boolean) {
val canonicalPath = canonicalizeInternal(dir)

val lookupResult = lookupPath(canonicalPath, createRootOnDemand = true)
Expand All @@ -384,7 +384,7 @@ class FakeFileSystem(
return
}

if (lookupResult?.element != null) {
if (mustCreate && lookupResult?.element != null) {
throw IOException("already exists: $dir")
}

Expand Down Expand Up @@ -427,7 +427,7 @@ class FakeFileSystem(
targetParent.children[canonicalTarget.nameBytes] = removed
}

override fun delete(path: Path) {
override fun delete(path: Path, mustExist: Boolean) {
val canonicalPath = canonicalizeInternal(path)

val lookupResult = lookupPath(
Expand All @@ -437,7 +437,11 @@ class FakeFileSystem(
)

if (lookupResult?.element == null) {
throw FileNotFoundException("no such file: $path")
if (mustExist) {
throw FileNotFoundException("no such file: $path")
} else {
return
}
}

if (lookupResult.element is Directory && lookupResult.element.children.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
*/
package okio

import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import okio.ByteString.Companion.encodeUtf8
import okio.ByteString.Companion.toByteString
import okio.Path.Companion.toPath
import okio.fakefilesystem.FakeFileSystem
import kotlin.test.BeforeTest
import kotlin.test.Ignore
import kotlin.test.Test
Expand All @@ -33,6 +27,12 @@ import kotlin.test.assertTrue
import kotlin.test.fail
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import okio.ByteString.Companion.encodeUtf8
import okio.ByteString.Companion.toByteString
import okio.Path.Companion.toPath
import okio.fakefilesystem.FakeFileSystem

/** This test assumes that okio-files/ is the current working directory when executed. */
@ExperimentalTime
Expand Down Expand Up @@ -691,12 +691,26 @@ abstract class AbstractFileSystemTest(
assertTrue(path in fileSystem.list(base))
}

@Test
fun createDirectoryMustCreate() {
val path = base / "create-directory"
fileSystem.createDirectory(path, mustCreate = true)
assertTrue(path in fileSystem.list(base))
}

@Test
fun createDirectoryAlreadyExists() {
val path = base / "already-exists"
fileSystem.createDirectory(path)
fileSystem.createDirectory(path)
}

@Test
fun createDirectoryAlreadyExistsMustCreateThrows() {
val path = base / "already-exists"
fileSystem.createDirectory(path)
val exception = assertFailsWith<IOException> {
fileSystem.createDirectory(path)
fileSystem.createDirectory(path, mustCreate = true)
}
assertTrue(exception !is FileNotFoundException)
}
Expand Down Expand Up @@ -725,6 +739,17 @@ abstract class AbstractFileSystemTest(
assertTrue(fileSystem.metadata(path).isDirectory)
}

@Test
fun createDirectoriesAlreadyExistsMustCreateThrows() {
val path = base / "already-exists"
fileSystem.createDirectory(path)
val exception = assertFailsWith<IOException> {
fileSystem.createDirectories(path, mustCreate = true)
}
assertTrue(exception !is FileNotFoundException)
assertTrue(fileSystem.metadata(path).isDirectory)
}

@Test
fun createDirectoriesParentDirectoryDoesNotExist() {
fileSystem.createDirectories(base / "a" / "b" / "c")
Expand Down Expand Up @@ -872,6 +897,14 @@ abstract class AbstractFileSystemTest(
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteFileMustExist() {
val path = base / "delete-file"
path.writeUtf8("delete me")
fileSystem.delete(path, mustExist = true)
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteEmptyDirectory() {
val path = base / "delete-empty-directory"
Expand All @@ -881,22 +914,36 @@ abstract class AbstractFileSystemTest(
}

@Test
fun deleteFailsOnNoSuchFile() {
fun deleteEmptyDirectoryMustExist() {
val path = base / "delete-empty-directory"
fileSystem.createDirectory(path)
fileSystem.delete(path, mustExist = true)
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteDoesNotExist() {
val path = base / "no-such-file"
fileSystem.delete(path)
}

@Test
fun deleteFailsOnNoSuchFileIfMustExist() {
val path = base / "no-such-file"
// TODO(jwilson): fix Windows to throw FileNotFoundException on deleting an absent file.
if (windowsLimitations) {
assertFailsWith<IOException> {
fileSystem.delete(path)
fileSystem.delete(path, mustExist = true)
}
} else {
assertFailsWith<FileNotFoundException> {
fileSystem.delete(path)
fileSystem.delete(path, mustExist = true)
}
}
}

@Test
fun deleteFailsOnNonemptyDirectory() {
fun deleteFailsOnNonEmptyDirectory() {
val path = base / "non-empty-directory"
fileSystem.createDirectory(path)
(path / "file.txt").writeUtf8("inside directory")
Expand All @@ -906,6 +953,17 @@ abstract class AbstractFileSystemTest(
assertTrue(exception !is FileNotFoundException)
}

@Test
fun deleteFailsOnNonEmptyDirectoryMustExist() {
val path = base / "non-empty-directory"
fileSystem.createDirectory(path)
(path / "file.txt").writeUtf8("inside directory")
val exception = assertFailsWith<IOException> {
fileSystem.delete(path, mustExist = true)
}
assertTrue(exception !is FileNotFoundException)
}

@Test
fun deleteRecursivelyFile() {
val path = base / "delete-recursively-file"
Expand All @@ -914,6 +972,14 @@ abstract class AbstractFileSystemTest(
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteRecursivelyFileMustExist() {
val path = base / "delete-recursively-file"
path.writeUtf8("delete me")
fileSystem.deleteRecursively(path, mustExist = true)
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteRecursivelyEmptyDirectory() {
val path = base / "delete-recursively-empty-directory"
Expand All @@ -923,22 +989,45 @@ abstract class AbstractFileSystemTest(
}

@Test
fun deleteRecursivelyFailsOnNoSuchFile() {
fun deleteRecursivelyEmptyDirectoryMustExist() {
val path = base / "delete-recursively-empty-directory"
fileSystem.createDirectory(path)
fileSystem.deleteRecursively(path, mustExist = true)
assertTrue(path !in fileSystem.list(base))
}

@Test
fun deleteRecursivelyNoSuchFile() {
val path = base / "no-such-file"
assertFailsWith<IOException> {
fileSystem.deleteRecursively(path)
}

@Test
fun deleteRecursivelyMustExistFailsOnNoSuchFile() {
val path = base / "no-such-file"
assertFailsWith<IOException> {
fileSystem.deleteRecursively(path, mustExist = true)
}
}

@Test
fun deleteRecursivelyNonemptyDirectory() {
fun deleteRecursivelyNonEmptyDirectory() {
val path = base / "delete-recursively-non-empty-directory"
fileSystem.createDirectory(path)
(path / "file.txt").writeUtf8("inside directory")
fileSystem.deleteRecursively(path)
assertTrue(path !in fileSystem.list(base))
assertTrue((path / "file.txt") !in fileSystem.list(base))
}
@Test
fun deleteRecursivelyNonEmptyDirectoryMustExist() {
val path = base / "delete-recursively-non-empty-directory"
fileSystem.createDirectory(path)
(path / "file.txt").writeUtf8("inside directory")
fileSystem.deleteRecursively(path, mustExist = true)
assertTrue(path !in fileSystem.list(base))
assertTrue((path / "file.txt") !in fileSystem.list(base))
}

@Test
fun deleteRecursivelyDeepHierarchy() {
Expand All @@ -950,6 +1039,16 @@ abstract class AbstractFileSystemTest(
assertEquals(listOf(), fileSystem.list(base))
}

@Test
fun deleteRecursivelyDeepHierarchyMustExist() {
fileSystem.createDirectory(base / "a")
fileSystem.createDirectory(base / "a" / "b")
fileSystem.createDirectory(base / "a" / "b" / "c")
(base / "a" / "b" / "c" / "d.txt").writeUtf8("inside deep hierarchy")
fileSystem.deleteRecursively(base / "a", mustExist = true)
assertEquals(listOf(), fileSystem.list(base))
}

@Test
fun deleteRecursivelyOnSymlinkToFileDeletesOnlyThatSymlink() {
if (!supportsSymlink()) return
Expand All @@ -962,6 +1061,19 @@ abstract class AbstractFileSystemTest(
assertEquals("b", baseB.readUtf8())
}


@Test
fun deleteRecursivelyOnSymlinkToFileDeletesOnlyThatSymlinkMustExist() {
if (!supportsSymlink()) return

val baseA = base / "a"
val baseB = base / "b"
baseB.writeUtf8("b")
fileSystem.createSymlink(baseA, baseB)
fileSystem.deleteRecursively(baseA, mustExist = true)
assertEquals("b", baseB.readUtf8())
}

@Test
fun deleteRecursivelyOnSymlinkToDirectoryDeletesOnlyThatSymlink() {
if (!supportsSymlink()) return
Expand All @@ -976,6 +1088,20 @@ abstract class AbstractFileSystemTest(
assertEquals("c", baseBC.readUtf8())
}

@Test
fun deleteRecursivelyOnSymlinkToDirectoryDeletesOnlyThatSymlinkMustExist() {
if (!supportsSymlink()) return

val baseA = base / "a"
val baseB = base / "b"
val baseBC = base / "b" / "c"
fileSystem.createDirectory(baseB)
baseBC.writeUtf8("c")
fileSystem.createSymlink(baseA, baseB)
fileSystem.deleteRecursively(baseA, mustExist = true)
assertEquals("c", baseBC.readUtf8())
}

@Test
fun deleteRecursivelyOnSymlinkCycleSucceeds() {
if (!supportsSymlink()) return
Expand All @@ -992,6 +1118,22 @@ abstract class AbstractFileSystemTest(
assertFalse(fileSystem.exists(base))
}

@Test
fun deleteRecursivelyOnSymlinkCycleSucceedsMustExist() {
if (!supportsSymlink()) return

val baseA = base / "a"
val baseAB = baseA / "b"
val baseAC = baseA / "c"

baseA.createDirectory()
baseAB.writeUtf8("ab")
fileSystem.createSymlink(baseAC, baseA)

fileSystem.deleteRecursively(base, mustExist = true)
assertFalse(fileSystem.exists(base))
}

@Test
fun deleteRecursivelyOnSymlinkToEnclosingDirectorySucceeds() {
if (!supportsSymlink()) return
Expand All @@ -1004,6 +1146,18 @@ abstract class AbstractFileSystemTest(
assertTrue(fileSystem.exists(base))
}

@Test
fun deleteRecursivelyOnSymlinkToEnclosingDirectorySucceedsMustExist() {
if (!supportsSymlink()) return

val baseA = base / "a"
fileSystem.createSymlink(baseA, ".".toPath())

fileSystem.deleteRecursively(baseA, mustExist = true)
assertFalse(fileSystem.exists(baseA))
assertTrue(fileSystem.exists(base))
}

@Test
fun fileMetadata() {
val minTime = clock.now()
Expand Down
Loading

0 comments on commit ad1c093

Please sign in to comment.