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
Chaos testing module #130
Chaos testing module #130
Conversation
about failed checks:
|
@IgorPerikov Don't worry about the docs thing - it's a known issue that the build attempts to perform the build docs step on the PR branches. We've tried to fix that a couple of times already but it seems to be elusive! Haven't had a chance to look over your code yet - will try to have a look soon. :) |
Obviously this is still WIP, but a couple of things about how we would envisage this going. Overall you're on the right track - just pointers really - not criticism! :) :
That was a bit of a braindump as well - if it doesn't make sense then just yell. :) |
the points you mentioned are really valuable, I agree with all of them, I'll get back with a new stuff later |
A few things I'd like to emphasize here:
|
@daviddenton kindly ping? |
release-maven-central.sh
Outdated
@@ -65,5 +65,6 @@ maven_publish "http4k-server-jetty" | |||
maven_publish "http4k-server-netty" | |||
maven_publish "http4k-server-undertow" | |||
maven_publish "http4k-serverless-lambda" | |||
maven_publish "http4k-testing-chaos" |
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.
For the moment we need to remove this line from the commit - because there is a cycle for when we create a new module - it needs to be uploaded to bintray, then we have to ask permission for it to be linked to JCenter, and only then can we sync it to maven. If we add this line now, it'll fail build that we release it in! :)
{ request -> | ||
if (chaosPolicy.shouldInject(request)) { | ||
behaviour.inject(request) | ||
next(request).header(LATENCY_HEADER, behaviour.javaClass.name) |
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.
This is no longer LATENCY only - just call it X-http4k-chaos or similar. We can also add the description of the behaviour as a method on the behaviour instance, and then use it to generate dynamic names based on what we did! :)
const val LATENCY_HEADER = "X-Chaos-Behaviour" | ||
|
||
object ChaosFilters { | ||
object ChaosPreFilter { |
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.
Can probably combine these into a single filter and then have 2 methods on the Policy shouldInject(Request) and shouldInject(Response) - both of which can default to false.
@IgorPerikov sorry for going quiet - given you comments I wasn't sure if you were still actively committing to the branch so left you to it! :) Anyway - it's a good start - I've left a couple of comments - the other thing that might help to drive out an API (specifically around the configuration) is to introduce further behaviours now:
|
* merge pre and post filters into single one * add inject(Response) & inject(Request) methods to behaviour interface * provide more chaos behaviours
@daviddenton new stuff is ready to review! When I was working under it, I realised, that it would be extremely conventional to have two methods for ChaosBehaviour as well - one for request and one for response latest changelist:
|
delete_version.sh
Outdated
@@ -48,5 +48,6 @@ maven_publish "http4k-server-jetty" | |||
maven_publish "http4k-server-netty" | |||
maven_publish "http4k-server-undertow" | |||
maven_publish "http4k-serverless-lambda" | |||
maven_publish "http4k-testing-chaos" |
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.
this needs to be removed as we won't publish the module until it's in jcenter..
} | ||
|
||
class ChaosException(message: String) : Exception(message) | ||
|
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.
generally, the pattern within the project is for this kind of thing to appear as an extension function of the parent type. So, for instance fun ChaosBehaviour.ThrowException()
. This one in particular could take an exception as an arg, and default to throw ChaosException as the default.
import org.http4k.core.Response | ||
import java.util.concurrent.ThreadLocalRandom | ||
|
||
interface ChaosPolicy { |
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.
ditto the remark about extension functions (from above)
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.
Have a look at my suggestions and let me know what you think :)
sure I will follow the project rules, but tbh I'm not really following this design principle - not a kotlin native speaker yet :). Is this what are you talking here? class ExceptionThrowingBehaviour : ChaosBehaviour {
override val description = "Exception"
override fun inject(response: Response) = throwException()
}
fun ChaosBehaviour.throwException(exception: Exception = ChaosException("Chaos behaviour injected!")): Response {
throw exception
} I guess my assumption is wrong, since it seems really weird for me, but I decided to show it just in case :) At first I thought about moving all the subtypes to be a companion object functions(pretty much like interface ChaosBehaviour {
... // signatures omitted for brevity
companion object {
fun throwException(exception: Exception = ChaosException("Chaos behaviour injected!")) = object : ChaosBehaviour {
override val description = "Exception"
override fun inject(response: Response): Response {
throw exception
}
}
}
} In addition to explanation, I'd be really grateful, if you could point me a few places in codebase where I could find an examples of this pattern for better understanding |
Hi @IgorPerikov - first off, I'm really, really sorry for the slow turnaround in this - I've been working up against a deadline so am completely flooded at the moment. It should be better by the end of next week so bear with me! Startups are hard! :) And whilst I'm waiting for a build to run.... Your intuition was completely right about ContentNegotiation being the template for what I meant - the companion object of the ChaosBehaviour interface would be where we would put these core behaviours. Then further behaviours can be added as extension methods TO the companion object, and hence we keep it all nice and discoverable in the IDE. This also means that you can drop the name "Behaviour" from each of the implementing classes, so you'd have: ChaosBehaviour.ThrowException**. I'd also maybe give the API use the option to use their own exception and keep the ChaosException as a default parameter in the function ** note the capitalization here - we follow a pattern where you can't really tell if a function is a constructor OR a class. This means that if we move from a function to a class at a later date, it doesn't break the API for the user. |
Hi, no need for apologize at all, no matter what is the reason. Thanks for clarification - clear and neat, will come back with update when it's ready |
seems like I am already back :) don't hesitate to mark/correct names in the code - I got used to them plus english is not my mother tongue |
Sorry (again) - I totally missed your message that you were done. Good news is that stupid deadline is done, so I can start to concentrate on other things! :) |
Glad that you meet your deadline! 🎆 |
According to #118
That's what I came up with - a draft implementation of latency injection filter
I also added header setting, so one can understand whether the request is slow because of chaos injection or some other reasons
cc @daviddenton