Skip to content

Commit df66b1e

Browse files
committed
add new tests
remove useless implementations
1 parent 604c094 commit df66b1e

File tree

5 files changed

+127
-40
lines changed

5 files changed

+127
-40
lines changed

KtorKMPFileCaching/build.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@ kotlin {
102102
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
103103
}
104104
androidNativeTest.dependencies {
105-
implementation(libs.slf4j.android)
106105
}
107106
jvmTest.dependencies {
108-
implementation(libs.slf4j.jvm)
109107
}
110108
val jsNodeTest by getting {
111109
}

KtorKMPFileCaching/src/commonMain/kotlin/fr/frankois944/ktorfilecaching/KtorFileCaching.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,6 @@ public class KtorFileCaching(
4444
@Suppress("ktlint:standard:property-naming")
4545
private val LOGGER = KtorSimpleLogger("fr.frankois944.ktorfilecaching")
4646

47-
init {
48-
if (!fileSystem.exists(rootStoredCachePath)) {
49-
fileSystem.createDirectories(rootStoredCachePath)
50-
}
51-
if (!fileSystem.exists(cacheDir)) {
52-
fileSystem.createDirectory(cacheDir)
53-
}
54-
}
55-
5647
/**
5748
* Purge cache
5849
* Delete in the filesystem all related files and directories
@@ -77,6 +68,11 @@ public class KtorFileCaching(
7768
url: Url,
7869
varyKeys: Map<String, String>,
7970
): CachedResponseData? = lock.withLock {
71+
LOGGER.debug("""
72+
FIND:
73+
url = $url
74+
varyKeys = $varyKeys
75+
""".trimIndent())
8076
val urlCacheDir = cacheDir.resolve(urlToPath(url))
8177
val varyKeyHash = hashVaryKeys(varyKeys)
8278
cacheSystem.read(urlCacheDir, varyKeyHash)?.let {
@@ -89,6 +85,11 @@ public class KtorFileCaching(
8985
val urlCacheDir = cacheDir.resolve(urlToPath)
9086
if (!cacheSystem.exist(urlCacheDir, null)) return emptySet()
9187

88+
LOGGER.debug("""
89+
FINDALL:
90+
url = $url
91+
""".trimIndent())
92+
9293
metadataCache[urlToPath]?.addAll(cacheSystem.contentOf(urlCacheDir).map { it.name })
9394
metadataCache[urlToPath]?.mapNotNull { varyKeyHash ->
9495
cacheSystem.read(urlCacheDir, varyKeyHash)?.let {
@@ -104,6 +105,11 @@ public class KtorFileCaching(
104105
val urlToPath = urlToPath(url)
105106
val urlCacheDir = cacheDir.resolve(urlToPath)
106107
val varyKeyHash = hashVaryKeys(data.varyKeys)
108+
LOGGER.debug("""
109+
STORE:
110+
url = $url
111+
varyKeys = ${data.varyKeys}
112+
""".trimIndent())
107113
cacheSystem.write(urlCacheDir, varyKeyHash, Json.encodeToString(SerializableCachedResponseData(data)))
108114
metadataCache[urlToPath]?.run {
109115
add(varyKeyHash)
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package fr.frankois944.ktorfilecaching
22

33
import io.ktor.client.HttpClient
4-
import io.ktor.client.request.get
4+
import io.ktor.client.request.*
55

66
class ApiClient(
77
val httpClient: HttpClient,
88
) {
99
suspend fun getIp() = httpClient.get("https://api.ipify.org/?format=json")
10+
suspend fun getIpWithParam(param: String) = httpClient.get("https://api.ipify.org/?format=json&param=$param")
11+
suspend fun getIpWithParamAndBody(param: String, body: String) = httpClient.post("https://api.ipify.org/?format=json&param=$param") {
12+
setBody(body)
13+
}
1014
}

KtorKMPFileCaching/src/commonTest/kotlin/fr/frankois944/ktorfilecaching/Test.kt

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import io.ktor.client.engine.mock.MockEngine
55
import io.ktor.client.engine.mock.respond
66
import io.ktor.client.plugins.cache.HttpCache
77
import io.ktor.client.plugins.cache.storage.CachedResponseData
8-
import io.ktor.client.plugins.logging.LogLevel
9-
import io.ktor.client.plugins.logging.Logging
8+
import io.ktor.client.plugins.logging.*
109
import io.ktor.client.statement.bodyAsText
1110
import io.ktor.http.HttpHeaders
1211
import io.ktor.http.HttpProtocolVersion
@@ -26,7 +25,7 @@ import kotlin.test.*
2625

2726
class CommonGreetingTest {
2827

29-
private val caching = KtorFileCaching(storedCacheDirectory = "testCache".toPath(), fileSystem = FakeFileSystem())
28+
private val caching = KtorFileCaching(storedCacheDirectory = "testCache".toPath(), fileSystem = FakeFileSystem())
3029

3130
@ExperimentalCoroutinesApi
3231
@BeforeTest
@@ -75,7 +74,7 @@ class CommonGreetingTest {
7574
}
7675

7776
@Test
78-
fun testKtorCache() = runTest {
77+
fun testSimpleKtorCache() = runTest {
7978
val mockEngine =
8079
MockEngine {
8180
respond(
@@ -108,7 +107,14 @@ class CommonGreetingTest {
108107
install(HttpCache) {
109108
publicStorage(caching)
110109
}
111-
install(Logging) { level = LogLevel.INFO }
110+
install(Logging) {
111+
logger = object : Logger {
112+
override fun log(message: String) {
113+
println(message)
114+
}
115+
}
116+
level = LogLevel.ALL
117+
}
112118
},
113119
)
114120

@@ -120,6 +126,76 @@ class CommonGreetingTest {
120126
client.httpClient.close()
121127
}
122128

129+
130+
@Test
131+
fun testComplexKtorCache() = runTest {
132+
var index = 0
133+
// build a list of request with 1 param with body
134+
// Pair<String, ByteReadChannel>, for 1 parameter and the body content
135+
val iteration = buildList {
136+
repeat(6) {
137+
add(
138+
Pair(
139+
"Request_param__${index++}",
140+
ByteReadChannel(
141+
"""
142+
{"ip":"127.0.0.1", "time" : ${Clock.System.now()}, "data" : ${Clock.System.now().nanosecondsOfSecond}}
143+
""".trimIndent()
144+
)
145+
)
146+
)
147+
}
148+
}
149+
// build a big list of randomized request from the original list of request
150+
val bodies = (iteration + iteration + iteration).shuffled()
151+
bodies.forEach { body ->
152+
val mockEngine =
153+
MockEngine {
154+
respond(
155+
content = body.second,
156+
status = HttpStatusCode.OK,
157+
headers = headersOf(
158+
Pair(
159+
HttpHeaders.ContentType,
160+
listOf("application/json")
161+
),
162+
Pair(
163+
HttpHeaders.Date,
164+
listOf(Clock.System.now().toString()),
165+
),
166+
Pair(
167+
HttpHeaders.CacheControl,
168+
listOf("max-age=600")
169+
)
170+
),
171+
)
172+
}
173+
174+
val client =
175+
ApiClient(
176+
HttpClient(mockEngine) {
177+
install(HttpCache) {
178+
publicStorage(caching)
179+
}
180+
install(Logging) {
181+
logger = object : Logger {
182+
override fun log(message: String) {
183+
println(message)
184+
}
185+
}
186+
level = LogLevel.ALL
187+
}
188+
},
189+
)
190+
191+
val firstResponse = client.getIpWithParam(body.first)
192+
val cachedResponse = client.getIpWithParam(body.first)
193+
assertEquals(firstResponse.bodyAsText(), cachedResponse.bodyAsText())
194+
assertEquals(firstResponse.headers, cachedResponse.headers)
195+
assertEquals(firstResponse.status, cachedResponse.status)
196+
}
197+
}
198+
123199
@Test
124200
fun testWithoutKtorCache() = runTest {
125201
val mockEngine =

README.md

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
This project add a file caching for [Ktor client caching](https://ktor.io/docs/client-caching.html).
44

5-
Currently, there is a Memory caching, it's the default [HttpCache](https://ktor.io/docs/client-caching.html#memory_cache) behavior of the plugin and a [file caching only for Java Target](https://ktor.io/docs/client-caching.html#persistent_cache).
5+
Currently, there is a Memory caching, it's the
6+
default [HttpCache](https://ktor.io/docs/client-caching.html#memory_cache) behavior of the plugin and
7+
a [file caching only for Java Target](https://ktor.io/docs/client-caching.html#persistent_cache).
68

79
The main goal is to make available file caching to many KMP target as possible.
810

9-
It's based on [OKIO dependency](https://square.github.io/okio/multiplatform/) and [kotlinx serialization](https://github.com/Kotlin/kotlinx.serialization).
11+
It's based on [OKIO dependency](https://square.github.io/okio/multiplatform/)
12+
and [kotlinx serialization](https://github.com/Kotlin/kotlinx.serialization).
1013

1114
## Example
1215

@@ -29,24 +32,24 @@ implementation("io.github.frankois944:ktorfilecaching:0.3")
2932

3033
The current supported targets are :
3134

32-
| Target | Supported |
33-
|-----------------------|------------|
34-
| jvm | |
35-
| js Node | |
36-
| js browser | |
37-
| wasm | |
38-
| iosX64 | |
39-
| iosArm64 | |
40-
| iosSimulatorArm64 | |
41-
| macosX64 | |
42-
| macosArm64 | |
43-
| watchosArm32 | |
44-
| watchosArm64 | |
45-
| watchosSimulatorArm64 | |
46-
| watchosX64 | |
47-
| tvosSimulatorArm64 | |
48-
| tvosX64 | |
49-
| mingwX64 | |
50-
| mingwX64 | |
51-
| linuxX64 | |
52-
| linuxArm64 | |
35+
| Target | Supported |
36+
|-----------------------|-----------|
37+
| jvm ||
38+
| js Node ||
39+
| js browser | |
40+
| wasmJS | |
41+
| iosX64 ||
42+
| iosArm64 ||
43+
| iosSimulatorArm64 ||
44+
| macosX64 ||
45+
| macosArm64 ||
46+
| watchosArm32 ||
47+
| watchosArm64 ||
48+
| watchosSimulatorArm64 ||
49+
| watchosX64 ||
50+
| tvosSimulatorArm64 ||
51+
| tvosX64 ||
52+
| mingwX64 ||
53+
| mingwX64 ||
54+
| linuxX64 ||
55+
| linuxArm64 ||

0 commit comments

Comments
 (0)