github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/helper/schema/provisioner_test.go (about)

     1  package schema
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/config"
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func TestProvisioner_impl(t *testing.T) {
    14  	var _ terraform.ResourceProvisioner = new(Provisioner)
    15  }
    16  
    17  func TestProvisionerValidate(t *testing.T) {
    18  	cases := []struct {
    19  		Name   string
    20  		P      *Provisioner
    21  		Config map[string]interface{}
    22  		Err    bool
    23  	}{
    24  		{
    25  			"Basic required field",
    26  			&Provisioner{
    27  				Schema: map[string]*Schema{
    28  					"foo": &Schema{
    29  						Required: true,
    30  						Type:     TypeString,
    31  					},
    32  				},
    33  			},
    34  			nil,
    35  			true,
    36  		},
    37  
    38  		{
    39  			"Basic required field set",
    40  			&Provisioner{
    41  				Schema: map[string]*Schema{
    42  					"foo": &Schema{
    43  						Required: true,
    44  						Type:     TypeString,
    45  					},
    46  				},
    47  			},
    48  			map[string]interface{}{
    49  				"foo": "bar",
    50  			},
    51  			false,
    52  		},
    53  	}
    54  
    55  	for i, tc := range cases {
    56  		t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
    57  			c, err := config.NewRawConfig(tc.Config)
    58  			if err != nil {
    59  				t.Fatalf("err: %s", err)
    60  			}
    61  
    62  			_, es := tc.P.Validate(terraform.NewResourceConfig(c))
    63  			if len(es) > 0 != tc.Err {
    64  				t.Fatalf("%d: %#v", i, es)
    65  			}
    66  		})
    67  	}
    68  }
    69  
    70  func TestProvisionerApply(t *testing.T) {
    71  	cases := []struct {
    72  		Name   string
    73  		P      *Provisioner
    74  		Conn   map[string]string
    75  		Config map[string]interface{}
    76  		Err    bool
    77  	}{
    78  		{
    79  			"Basic config",
    80  			&Provisioner{
    81  				ConnSchema: map[string]*Schema{
    82  					"foo": &Schema{
    83  						Type:     TypeString,
    84  						Optional: true,
    85  					},
    86  				},
    87  
    88  				Schema: map[string]*Schema{
    89  					"foo": &Schema{
    90  						Type:     TypeInt,
    91  						Optional: true,
    92  					},
    93  				},
    94  
    95  				ApplyFunc: func(ctx context.Context) error {
    96  					cd := ctx.Value(ProvConnDataKey).(*ResourceData)
    97  					d := ctx.Value(ProvConfigDataKey).(*ResourceData)
    98  					if d.Get("foo").(int) != 42 {
    99  						return fmt.Errorf("bad config data")
   100  					}
   101  					if cd.Get("foo").(string) != "bar" {
   102  						return fmt.Errorf("bad conn data")
   103  					}
   104  
   105  					return nil
   106  				},
   107  			},
   108  			map[string]string{
   109  				"foo": "bar",
   110  			},
   111  			map[string]interface{}{
   112  				"foo": 42,
   113  			},
   114  			false,
   115  		},
   116  	}
   117  
   118  	for i, tc := range cases {
   119  		t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
   120  			c, err := config.NewRawConfig(tc.Config)
   121  			if err != nil {
   122  				t.Fatalf("err: %s", err)
   123  			}
   124  
   125  			state := &terraform.InstanceState{
   126  				Ephemeral: terraform.EphemeralState{
   127  					ConnInfo: tc.Conn,
   128  				},
   129  			}
   130  
   131  			err = tc.P.Apply(
   132  				nil, state, terraform.NewResourceConfig(c))
   133  			if err != nil != tc.Err {
   134  				t.Fatalf("%d: %s", i, err)
   135  			}
   136  		})
   137  	}
   138  }
   139  
   140  func TestProvisionerApply_nilState(t *testing.T) {
   141  	p := &Provisioner{
   142  		ConnSchema: map[string]*Schema{
   143  			"foo": &Schema{
   144  				Type:     TypeString,
   145  				Optional: true,
   146  			},
   147  		},
   148  
   149  		Schema: map[string]*Schema{
   150  			"foo": &Schema{
   151  				Type:     TypeInt,
   152  				Optional: true,
   153  			},
   154  		},
   155  
   156  		ApplyFunc: func(ctx context.Context) error {
   157  			return nil
   158  		},
   159  	}
   160  
   161  	conf := map[string]interface{}{
   162  		"foo": 42,
   163  	}
   164  
   165  	c, err := config.NewRawConfig(conf)
   166  	if err != nil {
   167  		t.Fatalf("err: %s", err)
   168  	}
   169  
   170  	err = p.Apply(nil, nil, terraform.NewResourceConfig(c))
   171  	if err != nil {
   172  		t.Fatalf("err: %s", err)
   173  	}
   174  }
   175  
   176  func TestProvisionerStop(t *testing.T) {
   177  	var p Provisioner
   178  
   179  	// Verify stopch blocks
   180  	ch := p.StopContext().Done()
   181  	select {
   182  	case <-ch:
   183  		t.Fatal("should not be stopped")
   184  	case <-time.After(10 * time.Millisecond):
   185  	}
   186  
   187  	// Stop it
   188  	if err := p.Stop(); err != nil {
   189  		t.Fatalf("err: %s", err)
   190  	}
   191  
   192  	select {
   193  	case <-ch:
   194  	case <-time.After(10 * time.Millisecond):
   195  		t.Fatal("should be stopped")
   196  	}
   197  }
   198  
   199  func TestProvisionerStop_apply(t *testing.T) {
   200  	p := &Provisioner{
   201  		ConnSchema: map[string]*Schema{
   202  			"foo": &Schema{
   203  				Type:     TypeString,
   204  				Optional: true,
   205  			},
   206  		},
   207  
   208  		Schema: map[string]*Schema{
   209  			"foo": &Schema{
   210  				Type:     TypeInt,
   211  				Optional: true,
   212  			},
   213  		},
   214  
   215  		ApplyFunc: func(ctx context.Context) error {
   216  			<-ctx.Done()
   217  			return nil
   218  		},
   219  	}
   220  
   221  	conn := map[string]string{
   222  		"foo": "bar",
   223  	}
   224  
   225  	conf := map[string]interface{}{
   226  		"foo": 42,
   227  	}
   228  
   229  	c, err := config.NewRawConfig(conf)
   230  	if err != nil {
   231  		t.Fatalf("err: %s", err)
   232  	}
   233  
   234  	state := &terraform.InstanceState{
   235  		Ephemeral: terraform.EphemeralState{
   236  			ConnInfo: conn,
   237  		},
   238  	}
   239  
   240  	// Run the apply in a goroutine
   241  	doneCh := make(chan struct{})
   242  	go func() {
   243  		p.Apply(nil, state, terraform.NewResourceConfig(c))
   244  		close(doneCh)
   245  	}()
   246  
   247  	// Should block
   248  	select {
   249  	case <-doneCh:
   250  		t.Fatal("should not be done")
   251  	case <-time.After(10 * time.Millisecond):
   252  	}
   253  
   254  	// Stop!
   255  	p.Stop()
   256  
   257  	select {
   258  	case <-doneCh:
   259  	case <-time.After(10 * time.Millisecond):
   260  		t.Fatal("should be done")
   261  	}
   262  }
   263  
   264  func TestProvisionerStop_stopFirst(t *testing.T) {
   265  	var p Provisioner
   266  
   267  	// Stop it
   268  	if err := p.Stop(); err != nil {
   269  		t.Fatalf("err: %s", err)
   270  	}
   271  
   272  	select {
   273  	case <-p.StopContext().Done():
   274  	case <-time.After(10 * time.Millisecond):
   275  		t.Fatal("should be stopped")
   276  	}
   277  }