-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix concurrent invocations of InvocationRecorder #144
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,14 +18,10 @@ package com.careem.mockingbird.test | |
|
||
import kotlinx.atomicfu.AtomicInt | ||
import kotlinx.atomicfu.atomic | ||
import kotlin.native.concurrent.SharedImmutable | ||
import kotlin.test.assertEquals | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :( |
||
|
||
|
||
@SharedImmutable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SharedImmutable is ignored with the new memory model |
||
internal const val AWAIT_POOLING_TIME = 10L | ||
|
||
@SharedImmutable | ||
private val uuidGenerator: AtomicInt = atomic(0) | ||
|
||
public interface Mock { | ||
|
@@ -151,6 +147,16 @@ internal fun <T : Mock> T.rawVerify( | |
} | ||
} | ||
|
||
private fun assertEquals( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't find usage of this function. Where can it be used if it is private? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line 138. was using the function from kotlin.test There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I would change this, why not keeping the kotlin test? Mockingbird is a test library it shouldn't be used in production code anyway |
||
expected: Int, | ||
actual: Int, | ||
message: String | ||
) { | ||
if (expected != actual) { | ||
throw AssertionError(message) | ||
} | ||
} | ||
|
||
/** | ||
* Function to mock a function | ||
* @param methodName name of the method that you want to mock | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,21 +16,23 @@ | |
*/ | ||
package com.careem.mockingbird.test | ||
|
||
import co.touchlab.stately.collections.ConcurrentMutableMap | ||
|
||
internal class InvocationRecorder { | ||
|
||
private val recorder = mutableMapOf<String, MutableList<Invocation>>() | ||
private val responses = mutableMapOf<String, LinkedHashMap<Invocation, (Invocation) -> Any?>>() | ||
private val recorder = ConcurrentMutableMap<String, MutableList<Invocation>>() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks |
||
private val responses = ConcurrentMutableMap<String, LinkedHashMap<Invocation, (Invocation) -> Any?>>() | ||
|
||
/** | ||
* This function must be called by the mock when a function call is exceuted on it | ||
* This function must be called by the mock when a function call is executed on it | ||
* @param uuid the uuid of the mock | ||
* @param invocation the Invocation object @see [Invocation] | ||
*/ | ||
fun storeInvocation(uuid: String, invocation: Invocation) { | ||
if (!recorder.containsKey(uuid)) { | ||
recorder[uuid] = mutableListOf() | ||
recorder.block { map -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
val list = map.getOrPut(uuid) { mutableListOf() } | ||
list.add(invocation) | ||
} | ||
recorder[uuid]!!.add(invocation) | ||
} | ||
|
||
/** | ||
|
@@ -60,10 +62,10 @@ internal class InvocationRecorder { | |
* @param answer the lambda that must be invoked when the invocation happen | ||
*/ | ||
fun <T> storeAnswer(uuid: String, invocation: Invocation, answer: (Invocation) -> T) { | ||
if (!responses.containsKey(uuid)) { | ||
responses[uuid] = LinkedHashMap() | ||
responses.block { map -> | ||
val invocationsMap = map.getOrPut(uuid) { LinkedHashMap() } | ||
invocationsMap[invocation] = answer as (Invocation) -> Any? | ||
} | ||
responses[uuid]!![invocation] = answer as (Invocation) -> Any? | ||
} | ||
|
||
/** | ||
|
@@ -75,8 +77,8 @@ internal class InvocationRecorder { | |
* @return the mocked response, or null if relaxed (throws if not relaxed) | ||
*/ | ||
fun getResponse(uuid: String, invocation: Invocation, relaxed: Boolean = false): Any? { | ||
return if (uuid in responses.keys) { | ||
responses[uuid]!!.let { | ||
return if (uuid in responses) { | ||
responses.getValue(uuid).let { | ||
val lambda = findResponseByInvocation(it, invocation, relaxed) | ||
return@let lambda(invocation) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kotlin test was a production library :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep also in mind that mockingbird is a testing library as well, clients should use mockingbird as a test library