moto icon indicating copy to clipboard operation
moto copied to clipboard

Add record and replay feature

Open szopen321 opened this issue 2 years ago • 7 comments

proposed solution to https://github.com/spulec/moto/issues/5299

This allows to record calls to moto and replay them to restore the same state.

Feature breakdown:

  • endpoints to start and stop recording
  • endpoints to reset, download and upload recording
  • an endpoint to replay recorded entries
  • an endpoint to sed random seed

Notes and limitations:

  • not all services are covered by recording. Confirmed covered ones are: ec2, vpc and lambda.
  • methods with names starting with "Describe" are ommited in recording as they don't change state
  • to recreate randomly generated values (eg. ids of ec2 instances) while replaying one has to set random seed
  • recording is stored in a file to which path is stored in an environment variable
  • whether recording is by default enabled or not is also stored in an environment variable

szopen321 avatar Jul 11 '22 10:07 szopen321

Hi @bblommers! Here is another PR, I hope you'll like it. It seems like using mock.patch doesn't work in server mode. Do you have any solution to that or should I add raise SkipTest to solve this?

szopen321 avatar Jul 12 '22 13:07 szopen321

Hi @bblommers! I hope you are doing well. Is there any way I could help you with analysing this PR?

yoctozepto avatar Jul 21 '22 16:07 yoctozepto

Hi @szopen321 , thanks for the PR! This would be a really useful feature, and the approach makes sense overall.

The next major release will see some big changes, but maybe this can be part of a 4.x release. I'll have another look at the specifics of this PR after 4.0 is released.

As far as the mock.patch goes, it's not possible to mock this in ServerMode. So these should either be skipped, or rewritten as integration-style tests that work in both modes (like in test_set_seed).

bblommers avatar Jul 21 '22 22:07 bblommers

Hi @szopen321, if you don't mind, I'll work on this PR for a bit to see if I can get it to work for other services as well. So don't spend too much time worrying about getting the build to pass.

bblommers avatar Sep 12 '22 09:09 bblommers

@szopen321 What was your usecase for the random seed? The EC2 instance ID's happen to be generated using random.randint, but a lot of ID's are generated using UUID's, which are not affected by the set_seed-method.

I'm a little worried about the confusion this will cause if, when a user calls the set-seed-method, only half of the ID's end up being reproducible, and the other half are still random.

bblommers avatar Sep 14 '22 17:09 bblommers

Hi @bblommers! Thanks for noting that. What would you say about monkey patching UUID.uuid to make it use rand seed like this: uuid.UUID(int=rd.getrandbits(128), version=4) I would add the patching in set_seed method.

szopen321 avatar Sep 16 '22 12:09 szopen321

Hmmm.. patching a system-module can introduce a lot of unintended consequences and unexpected behaviour.

It maybe a better option to provide a utility-method that uses a semi-randomized uuid:

def get_uuid4():
    return uuid.UUID(int=rd.getrandbits(128), version=4)

Given the amount of UUID's that are used throughout Moto that is quite a wide-reaching change though. I'll make that change in a separate PR, otherwise it will be impossible to review.

This weekend I'll try and finish a PR that records all requests, for all services.

bblommers avatar Sep 16 '22 15:09 bblommers

Thank you again for getting this started @szopen321! It was incredibly useful to see this feature in action, and to have a good API/interface to guide the final implementation.

bblommers avatar Sep 28 '22 09:09 bblommers