github.com/richardmarshall/terraform@v0.9.5-0.20170429023105-15704cc6ee35/helper/schema/provider_test.go (about)

     1  package schema
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/config"
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func TestProvider_impl(t *testing.T) {
    14  	var _ terraform.ResourceProvider = new(Provider)
    15  }
    16  
    17  func TestProviderConfigure(t *testing.T) {
    18  	cases := []struct {
    19  		P      *Provider
    20  		Config map[string]interface{}
    21  		Err    bool
    22  	}{
    23  		{
    24  			P:      &Provider{},
    25  			Config: nil,
    26  			Err:    false,
    27  		},
    28  
    29  		{
    30  			P: &Provider{
    31  				Schema: map[string]*Schema{
    32  					"foo": &Schema{
    33  						Type:     TypeInt,
    34  						Optional: true,
    35  					},
    36  				},
    37  
    38  				ConfigureFunc: func(d *ResourceData) (interface{}, error) {
    39  					if d.Get("foo").(int) == 42 {
    40  						return nil, nil
    41  					}
    42  
    43  					return nil, fmt.Errorf("nope")
    44  				},
    45  			},
    46  			Config: map[string]interface{}{
    47  				"foo": 42,
    48  			},
    49  			Err: false,
    50  		},
    51  
    52  		{
    53  			P: &Provider{
    54  				Schema: map[string]*Schema{
    55  					"foo": &Schema{
    56  						Type:     TypeInt,
    57  						Optional: true,
    58  					},
    59  				},
    60  
    61  				ConfigureFunc: func(d *ResourceData) (interface{}, error) {
    62  					if d.Get("foo").(int) == 42 {
    63  						return nil, nil
    64  					}
    65  
    66  					return nil, fmt.Errorf("nope")
    67  				},
    68  			},
    69  			Config: map[string]interface{}{
    70  				"foo": 52,
    71  			},
    72  			Err: true,
    73  		},
    74  	}
    75  
    76  	for i, tc := range cases {
    77  		c, err := config.NewRawConfig(tc.Config)
    78  		if err != nil {
    79  			t.Fatalf("err: %s", err)
    80  		}
    81  
    82  		err = tc.P.Configure(terraform.NewResourceConfig(c))
    83  		if err != nil != tc.Err {
    84  			t.Fatalf("%d: %s", i, err)
    85  		}
    86  	}
    87  }
    88  
    89  func TestProviderResources(t *testing.T) {
    90  	cases := []struct {
    91  		P      *Provider
    92  		Result []terraform.ResourceType
    93  	}{
    94  		{
    95  			P:      &Provider{},
    96  			Result: []terraform.ResourceType{},
    97  		},
    98  
    99  		{
   100  			P: &Provider{
   101  				ResourcesMap: map[string]*Resource{
   102  					"foo": nil,
   103  					"bar": nil,
   104  				},
   105  			},
   106  			Result: []terraform.ResourceType{
   107  				terraform.ResourceType{Name: "bar"},
   108  				terraform.ResourceType{Name: "foo"},
   109  			},
   110  		},
   111  
   112  		{
   113  			P: &Provider{
   114  				ResourcesMap: map[string]*Resource{
   115  					"foo": nil,
   116  					"bar": &Resource{Importer: &ResourceImporter{}},
   117  					"baz": nil,
   118  				},
   119  			},
   120  			Result: []terraform.ResourceType{
   121  				terraform.ResourceType{Name: "bar", Importable: true},
   122  				terraform.ResourceType{Name: "baz"},
   123  				terraform.ResourceType{Name: "foo"},
   124  			},
   125  		},
   126  	}
   127  
   128  	for i, tc := range cases {
   129  		actual := tc.P.Resources()
   130  		if !reflect.DeepEqual(actual, tc.Result) {
   131  			t.Fatalf("%d: %#v", i, actual)
   132  		}
   133  	}
   134  }
   135  
   136  func TestProviderDataSources(t *testing.T) {
   137  	cases := []struct {
   138  		P      *Provider
   139  		Result []terraform.DataSource
   140  	}{
   141  		{
   142  			P:      &Provider{},
   143  			Result: []terraform.DataSource{},
   144  		},
   145  
   146  		{
   147  			P: &Provider{
   148  				DataSourcesMap: map[string]*Resource{
   149  					"foo": nil,
   150  					"bar": nil,
   151  				},
   152  			},
   153  			Result: []terraform.DataSource{
   154  				terraform.DataSource{Name: "bar"},
   155  				terraform.DataSource{Name: "foo"},
   156  			},
   157  		},
   158  	}
   159  
   160  	for i, tc := range cases {
   161  		actual := tc.P.DataSources()
   162  		if !reflect.DeepEqual(actual, tc.Result) {
   163  			t.Fatalf("%d: got %#v; want %#v", i, actual, tc.Result)
   164  		}
   165  	}
   166  }
   167  
   168  func TestProviderValidate(t *testing.T) {
   169  	cases := []struct {
   170  		P      *Provider
   171  		Config map[string]interface{}
   172  		Err    bool
   173  	}{
   174  		{
   175  			P: &Provider{
   176  				Schema: map[string]*Schema{
   177  					"foo": &Schema{},
   178  				},
   179  			},
   180  			Config: nil,
   181  			Err:    true,
   182  		},
   183  	}
   184  
   185  	for i, tc := range cases {
   186  		c, err := config.NewRawConfig(tc.Config)
   187  		if err != nil {
   188  			t.Fatalf("err: %s", err)
   189  		}
   190  
   191  		_, es := tc.P.Validate(terraform.NewResourceConfig(c))
   192  		if len(es) > 0 != tc.Err {
   193  			t.Fatalf("%d: %#v", i, es)
   194  		}
   195  	}
   196  }
   197  
   198  func TestProviderValidateResource(t *testing.T) {
   199  	cases := []struct {
   200  		P      *Provider
   201  		Type   string
   202  		Config map[string]interface{}
   203  		Err    bool
   204  	}{
   205  		{
   206  			P:      &Provider{},
   207  			Type:   "foo",
   208  			Config: nil,
   209  			Err:    true,
   210  		},
   211  
   212  		{
   213  			P: &Provider{
   214  				ResourcesMap: map[string]*Resource{
   215  					"foo": &Resource{},
   216  				},
   217  			},
   218  			Type:   "foo",
   219  			Config: nil,
   220  			Err:    false,
   221  		},
   222  	}
   223  
   224  	for i, tc := range cases {
   225  		c, err := config.NewRawConfig(tc.Config)
   226  		if err != nil {
   227  			t.Fatalf("err: %s", err)
   228  		}
   229  
   230  		_, es := tc.P.ValidateResource(tc.Type, terraform.NewResourceConfig(c))
   231  		if len(es) > 0 != tc.Err {
   232  			t.Fatalf("%d: %#v", i, es)
   233  		}
   234  	}
   235  }
   236  
   237  func TestProviderImportState_default(t *testing.T) {
   238  	p := &Provider{
   239  		ResourcesMap: map[string]*Resource{
   240  			"foo": &Resource{
   241  				Importer: &ResourceImporter{},
   242  			},
   243  		},
   244  	}
   245  
   246  	states, err := p.ImportState(&terraform.InstanceInfo{
   247  		Type: "foo",
   248  	}, "bar")
   249  	if err != nil {
   250  		t.Fatalf("err: %s", err)
   251  	}
   252  
   253  	if len(states) != 1 {
   254  		t.Fatalf("bad: %#v", states)
   255  	}
   256  	if states[0].ID != "bar" {
   257  		t.Fatalf("bad: %#v", states)
   258  	}
   259  }
   260  
   261  func TestProviderImportState_setsId(t *testing.T) {
   262  	var val string
   263  	stateFunc := func(d *ResourceData, meta interface{}) ([]*ResourceData, error) {
   264  		val = d.Id()
   265  		return []*ResourceData{d}, nil
   266  	}
   267  
   268  	p := &Provider{
   269  		ResourcesMap: map[string]*Resource{
   270  			"foo": &Resource{
   271  				Importer: &ResourceImporter{
   272  					State: stateFunc,
   273  				},
   274  			},
   275  		},
   276  	}
   277  
   278  	_, err := p.ImportState(&terraform.InstanceInfo{
   279  		Type: "foo",
   280  	}, "bar")
   281  	if err != nil {
   282  		t.Fatalf("err: %s", err)
   283  	}
   284  
   285  	if val != "bar" {
   286  		t.Fatal("should set id")
   287  	}
   288  }
   289  
   290  func TestProviderImportState_setsType(t *testing.T) {
   291  	var tVal string
   292  	stateFunc := func(d *ResourceData, meta interface{}) ([]*ResourceData, error) {
   293  		d.SetId("foo")
   294  		tVal = d.State().Ephemeral.Type
   295  		return []*ResourceData{d}, nil
   296  	}
   297  
   298  	p := &Provider{
   299  		ResourcesMap: map[string]*Resource{
   300  			"foo": &Resource{
   301  				Importer: &ResourceImporter{
   302  					State: stateFunc,
   303  				},
   304  			},
   305  		},
   306  	}
   307  
   308  	_, err := p.ImportState(&terraform.InstanceInfo{
   309  		Type: "foo",
   310  	}, "bar")
   311  	if err != nil {
   312  		t.Fatalf("err: %s", err)
   313  	}
   314  
   315  	if tVal != "foo" {
   316  		t.Fatal("should set type")
   317  	}
   318  }
   319  
   320  func TestProviderMeta(t *testing.T) {
   321  	p := new(Provider)
   322  	if v := p.Meta(); v != nil {
   323  		t.Fatalf("bad: %#v", v)
   324  	}
   325  
   326  	expected := 42
   327  	p.SetMeta(42)
   328  	if v := p.Meta(); !reflect.DeepEqual(v, expected) {
   329  		t.Fatalf("bad: %#v", v)
   330  	}
   331  }
   332  
   333  func TestProviderStop(t *testing.T) {
   334  	var p Provider
   335  
   336  	if p.Stopped() {
   337  		t.Fatal("should not be stopped")
   338  	}
   339  
   340  	// Verify stopch blocks
   341  	ch := p.StopContext().Done()
   342  	select {
   343  	case <-ch:
   344  		t.Fatal("should not be stopped")
   345  	case <-time.After(10 * time.Millisecond):
   346  	}
   347  
   348  	// Stop it
   349  	if err := p.Stop(); err != nil {
   350  		t.Fatalf("err: %s", err)
   351  	}
   352  
   353  	// Verify
   354  	if !p.Stopped() {
   355  		t.Fatal("should be stopped")
   356  	}
   357  
   358  	select {
   359  	case <-ch:
   360  	case <-time.After(10 * time.Millisecond):
   361  		t.Fatal("should be stopped")
   362  	}
   363  }
   364  
   365  func TestProviderStop_stopFirst(t *testing.T) {
   366  	var p Provider
   367  
   368  	// Stop it
   369  	if err := p.Stop(); err != nil {
   370  		t.Fatalf("err: %s", err)
   371  	}
   372  
   373  	// Verify
   374  	if !p.Stopped() {
   375  		t.Fatal("should be stopped")
   376  	}
   377  
   378  	select {
   379  	case <-p.StopContext().Done():
   380  	case <-time.After(10 * time.Millisecond):
   381  		t.Fatal("should be stopped")
   382  	}
   383  }
   384  
   385  func TestProviderReset(t *testing.T) {
   386  	var p Provider
   387  	stopCtx := p.StopContext()
   388  	p.MetaReset = func() error {
   389  		stopCtx = p.StopContext()
   390  		return nil
   391  	}
   392  
   393  	// cancel the current context
   394  	p.Stop()
   395  
   396  	if err := p.TestReset(); err != nil {
   397  		t.Fatal(err)
   398  	}
   399  
   400  	// the first context should have been replaced
   401  	if err := stopCtx.Err(); err != nil {
   402  		t.Fatal(err)
   403  	}
   404  
   405  	// we should not get a canceled context here either
   406  	if err := p.StopContext().Err(); err != nil {
   407  		t.Fatal(err)
   408  	}
   409  }