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(":crypto"))
implementation(project(":util"))
testImplementation("com.google.jimfs:jimfs:${Versions.jimfs}")
}
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.nio.channels.FileChannel
import java.nio.charset.Charset
import java.nio.file.CopyOption
import java.nio.file.FileVisitOption
import java.nio.file.Files
import java.nio.file.LinkOption
import java.nio.file.OpenOption
import java.nio.file.Path
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(
prefix: String? = null,
suffix: String? = null,

Loading…
Cancel
Save