pulumi / examples

Infrastructure, containers, and serverless apps to AWS, Azure, GCP, and Kubernetes... all deployed with Pulumi
https://www.pulumi.com
Apache License 2.0
2.35k stars 878 forks source link

add example of testing-unit-py with inline program #1007

Open benoitbayol opened 3 years ago

benoitbayol commented 3 years ago

For the moment the https://github.com/pulumi/examples/tree/master/testing-unit-py example is in fact a testing-unit-py-local-program.

It would be nice to have a testing-unit-py-inline-program since it is not obvious to create. (I did not manage yet to do it)

I also found a https://github.com/pulumi/examples/blob/master/testing-integration-py/test_s3_it.py but it is dedicated to integration hence creation of resources in a cloud provider.

Affected feature

Python Examples

lukehoban commented 3 years ago

@benoitbayol Could you give some more detail on what you are looking for here? The testing examples are indeed for testing normal Pulumi programs. If you are embedding Pulumi inside your own software with Automation API, you would need to apply testing approaches that make sense for the software you are building, and the existing unit testing and integration testing approaches we document may not apply directly. You can of course use Automation API to build your own testing frameworks - much like how the integration testing examples use a test framework that automation Pulumi deployments.

benoitbayol commented 3 years ago

With a local program we have


class MyMocks(pulumi.runtime.Mocks):
    def new_resource(self, args: pulumi.runtime.MockResourceArgs):
        outputs = args.inputs
        if args.typ == "aws:ec2/instance:Instance":
            outputs = {
                **args.inputs,
                "publicIp": "203.0.113.12",
                "publicDns": "ec2-203-0-113-12.compute-1.amazonaws.com",
            }
        return [args.name + '_id', outputs]
    def call(self, args: pulumi.runtime.MockCallArgs):
        if args.token == "aws:ec2/getAmi:getAmi":
            return {
                "architecture": "x86_64",
                "id": "ami-0eb1f3cdeeb8eed2a",
            }
        return {}

pulumi.runtime.set_mocks(MyMocks())

# Now actually import the code that creates resources, and then test it.
import infra

class TestingWithMocks(unittest.TestCase):
    # Test if the service has tags and a name tag.
    @pulumi.runtime.test
    def test_server_tags(self):
    // ....

I am looking to what to write in my test that will replace the import infra instructions since we will have a

def pulumi_program():
      group = ec2.SecurityGroup('web-secgrp', ingress=[
          # Uncomment to fail a test:
          #{ "protocol": "tcp", "from_port": 22, "to_port": 22, "cidr_blocks": ["0.0.0.0/0"] },
          { "protocol": "tcp", "from_port": 80, "to_port": 80, "cidr_blocks": ["0.0.0.0/0"] },
      ])

      user_data = '#!/bin/bash echo "Hello, World!" > index.html nohup python -m SimpleHTTPServer 80 &'

      ami_id = ec2.get_ami(
          most_recent=True,
          owners=["099720109477"],
          filters=[
              ec2.GetAmiFilterArgs(
                  name="name",
                  values=["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
              )]
      ).id

      server = ec2.Instance('web-server-www',
          instance_type="t2.micro",
          vpc_security_group_ids=[ group.id ], # reference the group object above
          # Comment out to fail a test:
          tags={'Name': 'webserver'},          # name tag
          # Uncomment to fail a test:
          #user_data=user_data)                # start a simple web server
          ami=ami_id)

I cannot have simply a call to pulumi_program() but I don't know what to do here. Do I have to create a stack with Automation ? but how I will parse the existing "mocked" infra in this settings. It is unclear for me to do the transition from a local_program to an inline_program with this testing example : https://github.com/pulumi/examples/blob/master/testing-unit-py/test_ec2.py

dang-gyg commented 3 years ago

I'm on the same boat here. Is there other alternative than to convert the inline program to the local program?