/fuse/src/test/java/com/github/kittinunf/fuse/FuseByteCacheTest.kt

https://github.com/kittinunf/Fuse · Kotlin · 261 lines · 202 code · 56 blank · 3 comment · 1 complexity · bab63683393bfb27edbff2b5f2cc5148 MD5 · raw file

  1. package com.github.kittinunf.fuse
  2. import com.github.kittinunf.fuse.core.ByteArrayDataConvertible
  3. import com.github.kittinunf.fuse.core.CacheBuilder
  4. import com.github.kittinunf.fuse.core.Source
  5. import com.github.kittinunf.fuse.core.build
  6. import com.github.kittinunf.fuse.core.fetch.NotFoundException
  7. import com.github.kittinunf.fuse.core.get
  8. import com.github.kittinunf.fuse.core.getWithSource
  9. import com.github.kittinunf.fuse.core.put
  10. import org.hamcrest.BaseMatcher
  11. import org.hamcrest.CoreMatchers.equalTo
  12. import org.hamcrest.CoreMatchers.hasItems
  13. import org.hamcrest.CoreMatchers.isA
  14. import org.hamcrest.CoreMatchers.not
  15. import org.hamcrest.CoreMatchers.notNullValue
  16. import org.hamcrest.CoreMatchers.nullValue
  17. import org.hamcrest.Description
  18. import org.hamcrest.Matcher
  19. import org.hamcrest.MatcherAssert.assertThat
  20. import org.junit.Before
  21. import org.junit.FixMethodOrder
  22. import org.junit.Test
  23. import org.junit.runners.MethodSorters
  24. import java.nio.charset.Charset
  25. import java.util.concurrent.CountDownLatch
  26. @FixMethodOrder(MethodSorters.NAME_ASCENDING)
  27. class FuseByteCacheTest : BaseTestCase() {
  28. companion object {
  29. private val tempDir = createTempDir().absolutePath
  30. val cache =
  31. CacheBuilder.config(tempDir, "Byte", ByteArrayDataConvertible()) {
  32. // do more configuration here
  33. }.build()
  34. }
  35. private var hasSetUp = false
  36. @Before
  37. fun initialize() {
  38. if (!hasSetUp) {
  39. hasSetUp = true
  40. }
  41. }
  42. @Test
  43. fun fetch() {
  44. val (result, source) = cache.getWithSource("hello", { "world".toByteArray() })
  45. val (value, error) = result
  46. assertThat(value, notNullValue())
  47. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("world"))
  48. assertThat(error, nullValue())
  49. assertThat(source, equalTo(Source.ORIGIN))
  50. }
  51. @Test
  52. fun hasKey() {
  53. val (value, error) = cache.get("hello")
  54. val hasKey = cache.hasKey("hello")
  55. assertThat(value, notNullValue())
  56. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("world"))
  57. assertThat(error, nullValue())
  58. assertThat(hasKey, equalTo(true))
  59. }
  60. @Test
  61. fun fetchSecondFail() {
  62. fun fetchFail(): ByteArray? = null
  63. val (result, source) = cache.getWithSource("fail", ::fetchFail)
  64. val (value, error) = result
  65. assertThat(value, nullValue())
  66. assertThat(error, notNullValue())
  67. assertThat(source, equalTo(Source.ORIGIN))
  68. }
  69. @Test
  70. fun fetchFromMemory() {
  71. val (result, source) = cache.getWithSource("hello", { "world".toByteArray() })
  72. val (value, error) = result
  73. assertThat(value, notNullValue())
  74. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("world"))
  75. assertThat(error, nullValue())
  76. assertThat(source, equalTo(Source.MEM))
  77. }
  78. @Test
  79. fun fetchFromDisk() {
  80. val (result, source) = cache.getWithSource("hello", { "world".toByteArray() })
  81. val (value, error) = result
  82. assertThat(value, notNullValue())
  83. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("world"))
  84. assertThat(error, nullValue())
  85. assertThat(source, equalTo(Source.MEM))
  86. // remove from memory cache
  87. cache.remove("hello", Source.MEM)
  88. val (result2, source2) = cache.getWithSource("hello", { "world".toByteArray() })
  89. val (value2, error2) = result2
  90. assertThat(value2, notNullValue())
  91. assertThat(value2!!.toString(Charset.defaultCharset()), equalTo("world"))
  92. assertThat(error2, nullValue())
  93. assertThat(source2, equalTo(Source.DISK))
  94. }
  95. @Test
  96. fun putStringSuccess1() {
  97. val (value, error) = cache.put("Test Put", "Hello world".toByteArray())
  98. assertThat(value, notNullValue())
  99. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("Hello world"))
  100. assertThat(error, nullValue())
  101. }
  102. @Test
  103. fun putStringSuccess2() {
  104. // this needs to be run sequentially after running the putStringSuccess1
  105. val (value, error) = cache.get("Test Put")
  106. assertThat(value, notNullValue())
  107. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("Hello world"))
  108. assertThat(error, nullValue())
  109. }
  110. @Test
  111. fun fetchFileSuccess() {
  112. val song = assetDir.resolve("sample_song.mp3")
  113. val (value, error) = cache.get(song)
  114. assertThat(value, notNullValue())
  115. assertThat(error, nullValue())
  116. }
  117. @Test
  118. fun fetchFileImageSuccess() {
  119. val image = assetDir.resolve("sample.jpg")
  120. val (value, error) = cache.get(image)
  121. assertThat(value, notNullValue())
  122. assertThat(error, nullValue())
  123. }
  124. @Test
  125. fun fetchFileFail() {
  126. val song = assetDir.resolve("not_found_song.mp3")
  127. val (value, error) = cache.get(song)
  128. assertThat(value, nullValue())
  129. assertThat(error, notNullValue())
  130. }
  131. @Test
  132. fun checkTimestamp() {
  133. cache.get("timestamp", { System.currentTimeMillis().toString().toByteArray() })
  134. Thread.sleep(2100)
  135. val timestamp = cache.getTimestamp("timestamp")
  136. assertThat(timestamp, not(equalTo(-1L)))
  137. val timeLimit = 2000L
  138. assertThat(
  139. System.currentTimeMillis() - timestamp,
  140. object : BaseMatcher<Long>() {
  141. override fun describeTo(description: Description) {
  142. description.appendText("$timestamp is over than $timeLimit")
  143. }
  144. override fun matches(item: Any?): Boolean = (item as Long) > timeLimit
  145. }
  146. )
  147. }
  148. @Test
  149. fun remove() {
  150. val (result, source) = cache.getWithSource("YOYO", { "yoyo".toByteArray() })
  151. val (value, error) = result
  152. assertThat(value, notNullValue())
  153. assertThat(value!!.toString(Charset.defaultCharset()), equalTo("yoyo"))
  154. assertThat(error, nullValue())
  155. assertThat(source, equalTo(Source.ORIGIN))
  156. cache.remove("YOYO", Source.MEM)
  157. cache.remove("YOYO", Source.DISK)
  158. val (anotherValue, anotherError) = cache.get("YOYO")
  159. assertThat(anotherValue, nullValue())
  160. assertThat(anotherError, notNullValue())
  161. assertThat(anotherError as NotFoundException, isA(NotFoundException::class.java))
  162. }
  163. @Test
  164. fun removeFromMem() {
  165. cache.put("remove", "test".toByteArray())
  166. val result = cache.remove("remove")
  167. assertThat(result, equalTo(true))
  168. val anotherResult = cache.remove("remove")
  169. assertThat(anotherResult, equalTo(false))
  170. }
  171. @Test
  172. fun removeFromDisk() {
  173. cache.put("remove", "test".toByteArray())
  174. val result = cache.remove("remove", Source.DISK)
  175. assertThat(result, equalTo(true))
  176. val anotherResult = cache.remove("remove", Source.MEM)
  177. assertThat(anotherResult, equalTo(true))
  178. val hasKey = cache.hasKey("remove")
  179. assertThat(hasKey, equalTo(false))
  180. }
  181. @Test
  182. fun removeThemAll() {
  183. val count = 10
  184. val lock = CountDownLatch(count)
  185. (1..count).forEach {
  186. cache.put("remove $it", "yoyo".toByteArray())
  187. }
  188. lock.wait()
  189. assertThat(cache.allKeys(), not(matchesEmpty(cache.allKeys())) as Matcher<in Set<String>>)
  190. (1..count).forEach {
  191. assertThat(
  192. cache.allKeys(),
  193. hasItems("remove $it")
  194. )
  195. }
  196. cache.removeAll()
  197. assertThat(cache.allKeys(), matchesEmpty(cache.allKeys()) as Matcher<in Set<String>>)
  198. }
  199. private inline fun <reified T> matchesEmpty(collection: Collection<T>) = object : BaseMatcher<T>() {
  200. override fun describeTo(description: Description) {
  201. description.appendText("$collection is not empty")
  202. }
  203. override fun matches(item: Any?): Boolean = (item as Collection<T>).isEmpty()
  204. }
  205. }