0

During the unit test the application code calls run_instances (a method of the boto3 EC2.Client).

How to intercept these calls and add TagSpecifications parameters to them?

I'm using moto for the test assertions (maybe it can set up some hooks to alter the calls?). Other option is straight patch of the EC2 client object, but it's too much.

Velkan
  • 7,067
  • 6
  • 43
  • 87
  • Moto doesn't have any hooks - it only intercepts boto3 calls. What is the reason the TagSpecifications-parameter cannot be part of the application code? – Bert Blommers Jul 07 '21 at 16:56

1 Answers1

0

Need to override the constructor boto3.client.

Assuming that tags are in LAUNCHTEMPLATE_TAGS_SPECIFICATIONS constant:

# Will be wrapping the EC2.Client object to change its methods.
ORIG_BOTO3_CLIENT = boto3.client


def decorate_run_instances_with_tags_creation(orig_run_instances):
    """Add some AWS tags."""
    def run_instances_emulate_tags_creation(*args, **kwargs):
        assert "TagSpecifications" not in kwargs, "application has created tags, there may be a conflict with the unit tests"
        kwargs["TagSpecifications"] = LAUNCHTEMPLATE_TAGS_SPECIFICATIONS
        return orig_run_instances(*args, **kwargs)
    return run_instances_emulate_tags_creation


def boto_client_factory_emulator(*args, **kwargs):
    """Retun an original EC2.Client with run_instances() that adds some AWS tags."""
    client = ORIG_BOTO3_CLIENT(*args, **kwargs)
    client.run_instances = decorate_run_instances_with_tags_creation(client.run_instances)
    return client

And then patch functions or classes:

@patch("my_module.boto3.client", Mock(side_effect=boto_client_factory_emulator))
Velkan
  • 7,067
  • 6
  • 43
  • 87