Add DiskStore tests

Signed-off-by: Graham <gpe@openrs2.dev>
pull/132/head
Graham 4 years ago
parent e8e2460d8e
commit ada90fb027
  1. 2
      cache/build.gradle.kts
  2. 669
      cache/src/test/java/dev/openrs2/cache/DiskStoreTest.kt
  3. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-eof-late-overwritten/main_file_cache.dat2
  4. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-eof-late-overwritten/main_file_cache.idx255
  5. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-eof-late/main_file_cache.dat2
  6. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-eof-late/main_file_cache.idx255
  7. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-eof-early-overwritten/main_file_cache.dat2
  8. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-eof-early-overwritten/main_file_cache.idx255
  9. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-eof-early/main_file_cache.dat2
  10. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-eof-early/main_file_cache.idx255
  11. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-archive-overwritten/main_file_cache.dat2
  12. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-archive-overwritten/main_file_cache.idx255
  13. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-archive/main_file_cache.dat2
  14. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-archive/main_file_cache.idx255
  15. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-block-number-overwritten/main_file_cache.dat2
  16. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-block-number-overwritten/main_file_cache.idx255
  17. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-block-number/main_file_cache.dat2
  18. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-block-number/main_file_cache.idx255
  19. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-group-overwritten/main_file_cache.dat2
  20. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-group-overwritten/main_file_cache.idx255
  21. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-group/main_file_cache.dat2
  22. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-invalid-group/main_file_cache.idx255
  23. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-outside-data-file-overwritten/main_file_cache.dat2
  24. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-outside-data-file-overwritten/main_file_cache.idx255
  25. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-outside-data-file/main_file_cache.dat2
  26. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-first-outside-data-file/main_file_cache.idx255
  27. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-eof-early-overwritten/main_file_cache.dat2
  28. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-eof-early-overwritten/main_file_cache.idx255
  29. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-eof-early/main_file_cache.dat2
  30. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-eof-early/main_file_cache.idx255
  31. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-archive-overwritten/main_file_cache.dat2
  32. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-archive-overwritten/main_file_cache.idx255
  33. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-archive/main_file_cache.dat2
  34. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-archive/main_file_cache.idx255
  35. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-block-number-overwritten/main_file_cache.dat2
  36. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-block-number-overwritten/main_file_cache.idx255
  37. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-block-number/main_file_cache.dat2
  38. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-block-number/main_file_cache.idx255
  39. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-group-overwritten/main_file_cache.dat2
  40. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-group-overwritten/main_file_cache.idx255
  41. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-group/main_file_cache.dat2
  42. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-invalid-group/main_file_cache.idx255
  43. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-outside-data-file-overwritten/main_file_cache.dat2
  44. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-outside-data-file-overwritten/main_file_cache.idx255
  45. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-outside-data-file/main_file_cache.dat2
  46. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/corrupt-second-outside-data-file/main_file_cache.idx255
  47. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty-archive/main_file_cache.dat2
  48. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty-archive/main_file_cache.idx255
  49. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty-archives/main_file_cache.dat2
  50. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty-archives/main_file_cache.idx0
  51. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty-archives/main_file_cache.idx255
  52. 0
      cache/src/test/resources/dev/openrs2/cache/disk-store/empty/main_file_cache.dat2
  53. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/fragmented/main_file_cache.dat2
  54. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/fragmented/main_file_cache.idx255
  55. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-extended-overwritten/main_file_cache.dat2
  56. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-extended-overwritten/main_file_cache.idx255
  57. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-extended/main_file_cache.dat2
  58. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-extended/main_file_cache.idx255
  59. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-overwritten/main_file_cache.dat2
  60. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks-overwritten/main_file_cache.idx255
  61. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks/main_file_cache.dat2
  62. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/multiple-blocks/main_file_cache.idx255
  63. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-extended-overwritten/main_file_cache.dat2
  64. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-extended-overwritten/main_file_cache.idx255
  65. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-extended/main_file_cache.dat2
  66. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-extended/main_file_cache.idx255
  67. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-overwritten/main_file_cache.dat2
  68. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-overwritten/main_file_cache.idx255
  69. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-removed/main_file_cache.dat2
  70. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block-removed/main_file_cache.idx255
  71. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block/main_file_cache.dat2
  72. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/single-block/main_file_cache.idx255
  73. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-extended-overwritten/main_file_cache.dat2
  74. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-extended-overwritten/main_file_cache.idx255
  75. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-extended/main_file_cache.dat2
  76. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-extended/main_file_cache.idx255
  77. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-overwritten/main_file_cache.dat2
  78. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks-overwritten/main_file_cache.idx255
  79. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks/main_file_cache.dat2
  80. BIN
      cache/src/test/resources/dev/openrs2/cache/disk-store/two-blocks/main_file_cache.idx255
  81. 32
      util/src/main/java/dev/openrs2/util/io/InputStreamExtensions.kt
  82. 58
      util/src/main/java/dev/openrs2/util/io/PathExtensions.kt

@ -8,6 +8,8 @@ dependencies {
implementation(project(":compress")) implementation(project(":compress"))
implementation(project(":crypto")) implementation(project(":crypto"))
implementation(project(":util")) implementation(project(":util"))
testImplementation("com.google.jimfs:jimfs:${Versions.jimfs}")
} }
publishing { publishing {

@ -0,0 +1,669 @@
package dev.openrs2.cache
import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs
import dev.openrs2.buffer.use
import dev.openrs2.util.io.recursiveCopy
import dev.openrs2.util.io.recursiveEquals
import io.netty.buffer.Unpooled
import org.junit.jupiter.api.assertThrows
import java.io.FileNotFoundException
import java.nio.file.Paths
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
object DiskStoreTest {
private val root = Paths.get(DiskStoreTest::class.java.getResource("disk-store").toURI())
@Test
fun testCreateArchive() {
writeTest("empty-archive") { store ->
store.create(255)
}
writeTest("empty-archives") { store ->
store.create(0)
store.create(255)
}
}
@Test
fun testArchiveExists() {
readTest("empty") { store ->
assertFalse(store.exists(0))
assertFalse(store.exists(1))
assertFalse(store.exists(254))
assertFalse(store.exists(255))
}
readTest("empty-archive") { store ->
assertFalse(store.exists(0))
assertFalse(store.exists(1))
assertFalse(store.exists(254))
assertTrue(store.exists(255))
}
readTest("empty-archives") { store ->
assertTrue(store.exists(0))
assertFalse(store.exists(1))
assertFalse(store.exists(254))
assertTrue(store.exists(255))
}
}
@Test
fun testListArchives() {
readTest("empty") { store ->
assertEquals(emptyList(), store.list())
}
readTest("empty-archive") { store ->
assertEquals(listOf(255), store.list())
}
readTest("empty-archives") { store ->
assertEquals(listOf(0, 255), store.list())
}
}
@Test
fun testRemoveArchive() {
overwriteTest("empty-archives", "empty-archive") { store ->
store.remove(0)
}
overwriteTest("empty-archive", "empty") { store ->
store.remove(255)
}
overwriteTest("empty", "empty") { store ->
store.remove(0)
store.remove(255)
}
}
@Test
fun testGroupExists() {
readTest("single-block") { store ->
assertFalse(store.exists(0, 0))
assertFalse(store.exists(255, 0))
assertTrue(store.exists(255, 1))
assertFalse(store.exists(255, 2))
}
}
@Test
fun testListGroups() {
readTest("single-block") { store ->
assertEquals(listOf(1), store.list(255))
}
readTest("single-block-extended") { store ->
assertEquals(listOf(65536), store.list(255))
}
}
@Test
fun testListNonExistent() {
readTest("empty") { store ->
assertThrows<FileNotFoundException> {
store.list(0)
}
}
}
@Test
fun testReadSingleBlock() {
readTest("single-block") { store ->
Unpooled.wrappedBuffer("OpenRS2".toByteArray()).use { expected ->
store.read(255, 1).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadSingleBlockExtended() {
readTest("single-block-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".toByteArray()).use { expected ->
store.read(255, 65536).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadTwoBlocks() {
readTest("two-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { expected ->
store.read(255, 1).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadTwoBlocksExtended() {
readTest("two-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { expected ->
store.read(255, 65536).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadMultipleBlocks() {
readTest("multiple-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { expected ->
store.read(255, 1).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadMultipleBlocksExtended() {
readTest("multiple-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { expected ->
store.read(255, 65536).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadNonExistent() {
readTest("single-block") { store ->
assertThrows<FileNotFoundException> {
store.read(0, 0)
}
assertThrows<FileNotFoundException> {
store.read(255, 0)
}
assertThrows<FileNotFoundException> {
store.read(255, 2)
}
}
}
@Test
fun testReadOverwritten() {
readTest("single-block-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("two-blocks-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("multiple-blocks-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(200).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testReadFragmented() {
readTest("fragmented") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { expected ->
for (j in 0 until 2) {
store.read(255, j).use { actual ->
assertEquals(expected, actual)
}
}
}
}
}
@Test
fun testWriteSingleBlock() {
writeTest("single-block") { store ->
Unpooled.wrappedBuffer("OpenRS2".toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testWriteSingleBlockExtended() {
writeTest("single-block-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
}
@Test
fun testWriteTwoBlocks() {
writeTest("two-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testWriteTwoBlocksExtended() {
writeTest("two-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
}
@Test
fun testWriteMultipleBlocks() {
writeTest("multiple-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testWriteMultipleBlocksExtended() {
writeTest("multiple-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
}
@Test
fun testWriteFragmented() {
writeTest("fragmented") { store ->
for (i in 1..2) {
Unpooled.wrappedBuffer("OpenRS2".repeat(i * 50).toByteArray()).use { buf ->
for (j in 0 until 2) {
store.write(255, j, buf.slice())
}
}
}
}
}
@Test
fun testOverwriteShorter() {
overwriteTest("single-block", "single-block-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("two-blocks", "two-blocks-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("multiple-blocks", "multiple-blocks-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(200).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testOverwriteShorterExtended() {
overwriteTest("single-block-extended", "single-block-extended-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
overwriteTest("two-blocks-extended", "two-blocks-extended-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
overwriteTest("multiple-blocks-extended", "multiple-blocks-extended-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(200).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
}
@Test
fun testOverwriteLonger() {
overwriteTest("single-block", "two-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("single-block", "multiple-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("two-blocks", "multiple-blocks") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testOverwriteLongerExtended() {
overwriteTest("single-block-extended", "two-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(100).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
overwriteTest("single-block-extended", "multiple-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
overwriteTest("two-blocks-extended", "multiple-blocks-extended") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1000).toByteArray()).use { buf ->
store.write(255, 65536, buf)
}
}
}
@Test
fun testRemoveGroup() {
overwriteTest("empty", "empty") { store ->
store.remove(0, 0)
}
overwriteTest("single-block", "single-block") { store ->
store.remove(255, 2)
}
overwriteTest("single-block", "single-block-removed") { store ->
store.remove(255, 1)
}
}
@Test
fun testReadCorrupt() {
readTest("corrupt-eof-late") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-first-eof-early") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-first-invalid-archive") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-first-invalid-block-number") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-first-invalid-group") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-first-outside-data-file") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-second-eof-early") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-second-invalid-archive") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-second-invalid-block-number") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-second-invalid-group") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
readTest("corrupt-second-outside-data-file") { store ->
assertThrows<StoreCorruptException> {
store.read(255, 1).release()
}
}
}
@Test
fun testOverwriteCorrupt() {
overwriteTest("corrupt-eof-late", "corrupt-eof-late-overwritten") { store ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1050).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-first-eof-early", "corrupt-first-eof-early-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-first-invalid-archive", "corrupt-first-invalid-archive-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-first-invalid-block-number", "corrupt-first-invalid-block-number-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-first-invalid-group", "corrupt-first-invalid-group-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-first-outside-data-file", "corrupt-first-outside-data-file-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-second-eof-early", "corrupt-second-eof-early-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-second-invalid-archive", "corrupt-second-invalid-archive-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest(
"corrupt-second-invalid-block-number",
"corrupt-second-invalid-block-number-overwritten"
) { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-second-invalid-group", "corrupt-second-invalid-group-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
overwriteTest("corrupt-second-outside-data-file", "corrupt-second-outside-data-file-overwritten") { store ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { buf ->
store.write(255, 1, buf)
}
}
}
@Test
fun testReadOverwrittenCorrupt() {
readTest("corrupt-eof-late-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("OpenRS2".repeat(1050).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-first-eof-early-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-first-invalid-archive-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-first-invalid-block-number-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-first-invalid-group-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-first-outside-data-file-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-second-eof-early-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-second-invalid-archive-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-second-invalid-block-number-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-second-invalid-group-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
readTest("corrupt-second-outside-data-file-overwritten") { store ->
store.read(255, 1).use { actual ->
Unpooled.wrappedBuffer("Hello".repeat(300).toByteArray()).use { expected ->
assertEquals(expected, actual)
}
}
}
}
private fun readTest(name: String, f: (Store) -> Unit) {
DiskStore.open(root.resolve(name)).use { store ->
f(store)
}
}
private fun writeTest(name: String, f: (Store) -> Unit) {
Jimfs.newFileSystem(Configuration.unix()).use { fs ->
val actual = fs.getPath("/cache")
DiskStore.create(actual).use { store ->
f(store)
}
val expected = root.resolve(name)
assertTrue(expected.recursiveEquals(actual))
}
}
private fun overwriteTest(src: String, name: String, f: (Store) -> Unit) {
Jimfs.newFileSystem(Configuration.unix()).use { fs ->
val actual = fs.getPath("/cache")
root.resolve(src).recursiveCopy(actual)
DiskStore.open(actual).use { store ->
f(store)
}
val expected = root.resolve(name)
assertTrue(expected.recursiveEquals(actual))
}
}
}

@ -0,0 +1,32 @@
package dev.openrs2.util.io
import java.io.InputStream
import java.util.Arrays
fun InputStream.contentEquals(other: InputStream): Boolean {
val buf1 = ByteArray(4096)
val buf2 = ByteArray(4096)
while (true) {
val n1 = read(buf1, 0, buf1.size)
if (n1 == -1) {
return other.read() == -1
}
var off = 0
var remaining = n1
while (remaining > 0) {
val n2 = other.read(buf2, off, remaining)
if (n2 == -1) {
return false
}
off += n2
remaining -= n2
}
if (!Arrays.equals(buf1, 0, n1, buf2, 0, n1)) {
return false
}
}
}

@ -4,7 +4,10 @@ import java.io.BufferedWriter
import java.io.OutputStream import java.io.OutputStream
import java.nio.channels.FileChannel import java.nio.channels.FileChannel
import java.nio.charset.Charset import java.nio.charset.Charset
import java.nio.file.CopyOption
import java.nio.file.FileVisitOption
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.LinkOption
import java.nio.file.OpenOption import java.nio.file.OpenOption
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
@ -19,6 +22,61 @@ fun Path.fsync() {
} }
} }
fun Path.recursiveCopy(
destination: Path,
visitOptions: Array<FileVisitOption> = emptyArray(),
copyOptions: Array<CopyOption> = emptyArray()
) {
for (sourceFile in Files.walk(this, *visitOptions)) {
val destinationFile = destination.resolve(this.relativize(sourceFile).toString())
if (Files.isDirectory(sourceFile)) {
Files.createDirectory(destinationFile)
} else {
Files.copy(sourceFile, destinationFile, *copyOptions)
}
}
}
fun Path.recursiveEquals(
other: Path,
linkOptions: Array<LinkOption> = emptyArray(),
openOptions: Array<OpenOption> = emptyArray()
): Boolean {
val list1 = Files.newDirectoryStream(this).use { stream ->
stream.map { this.relativize(it).toString() }.sorted().toList()
}
val list2 = Files.newDirectoryStream(other).use { stream ->
stream.map { other.relativize(it).toString() }.sorted().toList()
}
if (list1 != list2) {
return false
}
for (file in list1) {
val file1 = this.resolve(file)
val file2 = other.resolve(file)
if (Files.isDirectory(file1, *linkOptions)) {
if (!Files.isDirectory(file2, *linkOptions)) {
return false
}
} else {
Files.newInputStream(file1, *openOptions).use { input1 ->
Files.newInputStream(file2, *openOptions).use { input2 ->
if (!input1.contentEquals(input2)) {
return false
}
}
}
}
}
return true
}
inline fun <T> useTempFile( inline fun <T> useTempFile(
prefix: String? = null, prefix: String? = null,
suffix: String? = null, suffix: String? = null,

Loading…
Cancel
Save