Skip to content
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

Support flexible StaminaTestKit #56

Open
wuliaososhunhun opened this issue Oct 12, 2016 · 4 comments
Open

Support flexible StaminaTestKit #56

wuliaososhunhun opened this issue Oct 12, 2016 · 4 comments

Comments

@wuliaososhunhun
Copy link

wuliaososhunhun commented Oct 12, 2016

Hi,

we are using the StaminaTestKit for our persist test. Our use case is only keep the latest version of persisted events. When we upgrade domain to new version with additional fields, the automatic generating test cannot pass easily.

e.g. ClassV1(field1) -> ClassV2(field1, field2) while field 1 and 2 are completely independent. the migration rule should be add field2 with default values which should be empty normally. That makes our test harder. if we use ClassV2 with empty field2 as sample to test, it should pass all the test but it will not test the field2 with data inside. if we use ClassV2 with random data in field2 as sample, it will break the test from V1 -> V2 while V2 test should be fine.

Currently, we just make a hacky approach by re-writing (mostly copy paste as most method inside is private which cannot be re-used easily) the StaminaTestKit. I mainly make generateRoundtripTestFor and generateStoredVersionsDeserializationTestsFor public so we can use them separately. Meanwhile, we change generateStoredVersionsDeserializationTestsFor to have additional field toVersion so we can decide the version range not always from version 1 to latest. By doing this, we can have ClassV2 with empty field2 sample for migration from V1 to V2 while another ClassV2 with data to check V2 only. If there are more fields in the future, we can test starting from V2 without changing anything before V2.

I believe this would make the test more flexible. Could you let me know what is your thought?

Thanks,
Yanyang

@raboof
Copy link
Member

raboof commented Oct 12, 2016

Hello Yanyang, thanks for your question!

When you say you "only keep the latest version of persisted events", I understand you mean you only have a case class for the latest version, but 'old' persisted events are still in storage? If so that's indeed exactly how stamina is designed to be used.

When introducing ClassV2, it is indeed useful to have a testcase both for the situation where field2 is empty, and a testcase for the situation where field2 is filled. This should be possible with StaminaTestKit without hacking or exposing private parts.

You will have to add a 'sample id' to distinguish different tests for the same event type. It might look something like this:

persisters.generateTestsFor(
      sample(ClassV2("foo", None)),
      sample("with-field2", ClassV2("bar", Some("baz"))))

We should definitely add an example of this to the README, let's not close this issue before we fix that.

I suspect this should fix your use case, though I don't completely understand your last paragraph. Can you confirm this helps? Or otherwise perhaps rephrase, or share some example code of what you want to achieve?

@wuliaososhunhun
Copy link
Author

wuliaososhunhun commented Oct 13, 2016

Hi,

I am trying to use your solution while I got this

  • should deserialize the stored serialized form of ClassV2-with-surrogateBins version 1 *** FAILED ***
    [info] While testing that the older serialized version 1 of sample with key ClassV2 and sample id with-surrogateBins was not found

The main problem is that we no longer keeping the old version persisters which causes the issue. In other word, for the case class to be persisted, only 1 persister will exist in the code anytime which is always the one with highest version. This should make my question more clear.
To my last paragraph, the code of my test as follows:

val v2State = ClassV2("bar", Some("baz"))

val v1to2State = v2State.copy(field2 = None)

persisters.generateRoundtripTestFor(sample(v2State)) // step 1
persisters.generateStoredVersionsDeserializationTestsFor(sample(v1to2State), 1, 1) // step 2

  • Step 1 will do things as usual while deserialize the stored serialized form of ClassV2 version 2(always latest) in addition.
  • Step2 should deserialize the stored serialized form from version 1 to version 2 (exclude version 2) as specified in the method

@psliwa
Copy link
Contributor

psliwa commented Oct 17, 2016

I have similar problem as @wuliaososhunhun.

I have SomePersistedSnapshot(something: SomePersistedState), SomePersistedState is trait and in V2 version I've introduced new implementation for this trait. Currently I am not able to test persistence for new class of SomePersistedState, because when I create sample TestKit for SomePersistedSnapshot(something: BrandNewSomePersistedState) is complaining that there is not sample file for v1. In this case it doesn't make sense, because it is normal that this is completely new value and there is not v1 json which is able to represent new class.

I think that fromVersion property for Sample class would solve this problem, I can submit PR for that - is it ok?

@raboof
Copy link
Member

raboof commented Nov 20, 2016

Yes, it indeed looks like this is missing from the current testkit.

Making the fromVersion (with default value) a property of the sample seems to make sense to me - a PR would be much appreciate it.

I wonder if we could/should make a check that ensures at least one sample goes all the way back to version 1?

psliwa added a commit to psliwa/stamina that referenced this issue Nov 20, 2016
raboof added a commit that referenced this issue Mar 29, 2017
[#56] define "fromVersionNumber" for samples in TestKit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants