Skip to content

Commit

Permalink
Update the Go unit test example (pulumi#621)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikhailshilkov committed Apr 1, 2020
1 parent 02f9eb2 commit 0df1a3a
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 47 deletions.
62 changes: 53 additions & 9 deletions testing-unit-go/main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,69 @@
package main

import (
"github.com/pulumi/pulumi-aws/sdk/go/aws/s3"
"github.com/pulumi/pulumi-aws/sdk/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/go/pulumi"
)

// CreateBucket is the function we want to test.
func CreateBucket(ctx *pulumi.Context) (*s3.Bucket, error) {
// Create an AWS resource (S3 Bucket)
return s3.NewBucket(ctx, "my-bucket", nil)
type infrastructure struct {
group *ec2.SecurityGroup
server *ec2.Instance
}

func createInfrastructure(ctx *pulumi.Context) (*infrastructure, error) {
group, err := ec2.NewSecurityGroup(ctx, "web-secgrp", &ec2.SecurityGroupArgs{
Ingress: ec2.SecurityGroupIngressArray{
// Uncomment to fail a test:
//ec2.SecurityGroupIngressArgs{
// Protocol: pulumi.String("tcp"),
// FromPort: pulumi.Int(22),
// ToPort: pulumi.Int(22),
// CidrBlocks: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
//},
ec2.SecurityGroupIngressArgs{
Protocol: pulumi.String("tcp"),
FromPort: pulumi.Int(80),
ToPort: pulumi.Int(80),
CidrBlocks: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
},
},
})
if err != nil {
return nil, err
}

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

server, err := ec2.NewInstance(ctx, "web-server-www", &ec2.InstanceArgs{
InstanceType: pulumi.String("t2-micro"),
SecurityGroups: pulumi.StringArray{group.ID()}, // reference the group object above
Ami: pulumi.String("ami-c55673a0"), // AMI for us-east-2 (Ohio)
// Comment out to fail a test:
Tags: pulumi.Map{"Name": pulumi.String("webserver")},
// Uncomment to fail a test:
//UserData: pulumi.String(userData), // start a simple web server
})
if err != nil {
return nil, err
}

return &infrastructure{
group: group,
server: server,
}, nil
}

func main() {
pulumi.Run(func (ctx *pulumi.Context) error {
bucket, err := CreateBucket(ctx)
pulumi.Run(func(ctx *pulumi.Context) error {
infra, err := createInfrastructure(ctx)
if err != nil {
return err
}

// Export the name of the bucket
ctx.Export("bucketName", bucket.ID())
ctx.Export("group", infra.group.ID())
ctx.Export("server", infra.server.ID())
ctx.Export("publicIp", infra.server.PublicIp)
ctx.Export("publicHostName", infra.server.PublicDns)
return nil
})
}
91 changes: 53 additions & 38 deletions testing-unit-go/main_test.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,78 @@
package main

import (
"sync"
"testing"

"github.com/pulumi/pulumi-aws/sdk/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/go/common/resource"
"github.com/pulumi/pulumi/sdk/go/pulumi"
"github.com/stretchr/testify/assert"
)

type testMonitor struct {
CallF func(tok string, args resource.PropertyMap, provider string) (resource.PropertyMap, error)
NewResourceF func(typeToken, name string, inputs resource.PropertyMap,
provider, id string) (string, resource.PropertyMap, error)
}
type mocks int

func (m *testMonitor) Call(tok string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
if m.CallF == nil {
return resource.PropertyMap{}, nil
}
return m.CallF(tok, args, provider)
// Create the mock.
func (mocks) NewResource(typeToken, name string, inputs resource.PropertyMap, provider, id string) (string, resource.PropertyMap, error) {
return name + "_id", inputs, nil
}

func (m *testMonitor) NewResource(typeToken, name string, inputs resource.PropertyMap,
provider, id string) (string, resource.PropertyMap, error) {

if m.NewResourceF == nil {
return name, resource.PropertyMap{}, nil
}
return m.NewResourceF(typeToken, name, inputs, provider, id)
func (mocks) Call(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
return args, nil
}

func TestCreateBucket(t *testing.T) {
bucketName := "my-bucket-unique-name"

mocks := &testMonitor{
NewResourceF: func(typeToken, name string, inputs resource.PropertyMap,
provider, id string) (string, resource.PropertyMap, error) {
assert.Equal(t, "aws:s3/bucket:Bucket", typeToken)
return id, resource.NewPropertyMapFromMap(map[string]interface{}{
"bucket": bucketName,
}), nil
},
}

// Applying unit tests.
func TestInfrastructure(t *testing.T) {
err := pulumi.RunErr(func(ctx *pulumi.Context) error {
bucket, err := CreateBucket(ctx)
infra, err := createInfrastructure(ctx)
assert.NoError(t, err)

resultChan := make(chan string)
var wg sync.WaitGroup
wg.Add(3)

// Test if the service has tags and a name tag.
pulumi.All(infra.server.URN(), infra.server.Tags).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
tags := all[1].(map[string]interface{})

assert.Containsf(t, tags, "Name", "missing a Name tag on server %v", urn)
wg.Done()
return nil
})

// Test if the instance is configured with user_data.
pulumi.All(infra.server.URN(), infra.server.UserData).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
userData := all[1].(*string)

bucket.Bucket.ApplyT(func(val string) (string, error) {
resultChan <- val
return val, nil
assert.Nilf(t, userData, "illegal use of userData on server %v", urn)
wg.Done()
return nil
})

actual := <-resultChan
assert.Equal(t, bucketName, actual)
// Test if port 22 for ssh is exposed.
pulumi.All(infra.group.URN(), infra.group.Ingress).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
ingress := all[1].([]ec2.SecurityGroupIngress)

for _, i := range ingress {
openToInternet := false
for _, b := range i.CidrBlocks {
if b == "0.0.0.0/0" {
openToInternet = true
break
}
}

assert.Falsef(t, i.FromPort == 22 && openToInternet, "illegal SSH port 22 open to the Internet (CIDR 0.0.0.0/0) on group %v", urn)
}

wg.Done()
return nil
})

wg.Wait()
return nil
}, pulumi.WithMocks("project", "stack", mocks))
}, pulumi.WithMocks("project", "stack", mocks(0)))
assert.NoError(t, err)
}

0 comments on commit 0df1a3a

Please sign in to comment.