github.com/mehmetalisavas/terraform@v0.7.10/terraform/graph_builder_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/dag"
     9  )
    10  
    11  func TestBasicGraphBuilder_impl(t *testing.T) {
    12  	var _ GraphBuilder = new(BasicGraphBuilder)
    13  }
    14  
    15  func TestBasicGraphBuilder(t *testing.T) {
    16  	b := &BasicGraphBuilder{
    17  		Steps: []GraphTransformer{
    18  			&testBasicGraphBuilderTransform{1},
    19  		},
    20  	}
    21  
    22  	g, err := b.Build(RootModulePath)
    23  	if err != nil {
    24  		t.Fatalf("err: %s", err)
    25  	}
    26  
    27  	if !reflect.DeepEqual(g.Path, RootModulePath) {
    28  		t.Fatalf("bad: %#v", g.Path)
    29  	}
    30  
    31  	actual := strings.TrimSpace(g.String())
    32  	expected := strings.TrimSpace(testBasicGraphBuilderStr)
    33  	if actual != expected {
    34  		t.Fatalf("bad: %s", actual)
    35  	}
    36  }
    37  
    38  func TestBasicGraphBuilder_validate(t *testing.T) {
    39  	b := &BasicGraphBuilder{
    40  		Steps: []GraphTransformer{
    41  			&testBasicGraphBuilderTransform{1},
    42  			&testBasicGraphBuilderTransform{2},
    43  		},
    44  		Validate: true,
    45  	}
    46  
    47  	_, err := b.Build(RootModulePath)
    48  	if err == nil {
    49  		t.Fatal("should error")
    50  	}
    51  }
    52  
    53  func TestBasicGraphBuilder_validateOff(t *testing.T) {
    54  	b := &BasicGraphBuilder{
    55  		Steps: []GraphTransformer{
    56  			&testBasicGraphBuilderTransform{1},
    57  			&testBasicGraphBuilderTransform{2},
    58  		},
    59  		Validate: false,
    60  	}
    61  
    62  	_, err := b.Build(RootModulePath)
    63  	if err != nil {
    64  		t.Fatalf("expected no error, got: %s", err)
    65  	}
    66  }
    67  
    68  func TestBuiltinGraphBuilder_impl(t *testing.T) {
    69  	var _ GraphBuilder = new(BuiltinGraphBuilder)
    70  }
    71  
    72  // This test is not meant to test all the transforms but rather just
    73  // to verify we get some basic sane graph out. Special tests to ensure
    74  // specific ordering of steps should be added in other tests.
    75  func TestBuiltinGraphBuilder(t *testing.T) {
    76  	b := &BuiltinGraphBuilder{
    77  		Root:     testModule(t, "graph-builder-basic"),
    78  		Validate: true,
    79  	}
    80  
    81  	g, err := b.Build(RootModulePath)
    82  	if err != nil {
    83  		t.Fatalf("err: %s", err)
    84  	}
    85  
    86  	actual := strings.TrimSpace(g.String())
    87  	expected := strings.TrimSpace(testBuiltinGraphBuilderBasicStr)
    88  	if actual != expected {
    89  		t.Fatalf("bad: %s", actual)
    90  	}
    91  }
    92  
    93  func TestBuiltinGraphBuilder_Verbose(t *testing.T) {
    94  	b := &BuiltinGraphBuilder{
    95  		Root:     testModule(t, "graph-builder-basic"),
    96  		Validate: true,
    97  		Verbose:  true,
    98  	}
    99  
   100  	g, err := b.Build(RootModulePath)
   101  	if err != nil {
   102  		t.Fatalf("err: %s", err)
   103  	}
   104  
   105  	actual := strings.TrimSpace(g.String())
   106  	expected := strings.TrimSpace(testBuiltinGraphBuilderVerboseStr)
   107  	if actual != expected {
   108  		t.Fatalf("bad: %s", actual)
   109  	}
   110  }
   111  
   112  // This tests that the CreateBeforeDestoryTransformer is not present when
   113  // we perform a "terraform destroy" operation. We don't actually do anything
   114  // else.
   115  func TestBuiltinGraphBuilder_CreateBeforeDestroy_Destroy_Bypass(t *testing.T) {
   116  	b := &BuiltinGraphBuilder{
   117  		Root:     testModule(t, "graph-builder-basic"),
   118  		Validate: true,
   119  		Destroy:  true,
   120  	}
   121  
   122  	steps := b.Steps([]string{})
   123  
   124  	actual := false
   125  	expected := false
   126  	for _, v := range steps {
   127  		switch v.(type) {
   128  		case *CreateBeforeDestroyTransformer:
   129  			actual = true
   130  		}
   131  	}
   132  
   133  	if actual != expected {
   134  		t.Fatalf("bad: CreateBeforeDestroyTransformer still in root path")
   135  	}
   136  }
   137  
   138  // This tests that the CreateBeforeDestoryTransformer *is* present
   139  // during a non-destroy operation (ie: Destroy not set).
   140  func TestBuiltinGraphBuilder_CreateBeforeDestroy_NonDestroy_Present(t *testing.T) {
   141  	b := &BuiltinGraphBuilder{
   142  		Root:     testModule(t, "graph-builder-basic"),
   143  		Validate: true,
   144  	}
   145  
   146  	steps := b.Steps([]string{})
   147  
   148  	actual := false
   149  	expected := true
   150  	for _, v := range steps {
   151  		switch v.(type) {
   152  		case *CreateBeforeDestroyTransformer:
   153  			actual = true
   154  		}
   155  	}
   156  
   157  	if actual != expected {
   158  		t.Fatalf("bad: CreateBeforeDestroyTransformer not in root path")
   159  	}
   160  }
   161  
   162  // This tests a cycle we got when a CBD resource depends on a non-CBD
   163  // resource. This cycle shouldn't happen in the general case anymore.
   164  func TestBuiltinGraphBuilder_cbdDepNonCbd(t *testing.T) {
   165  	b := &BuiltinGraphBuilder{
   166  		Root:     testModule(t, "graph-builder-cbd-non-cbd"),
   167  		Validate: true,
   168  	}
   169  
   170  	_, err := b.Build(RootModulePath)
   171  	if err != nil {
   172  		t.Fatalf("err: %s", err)
   173  	}
   174  }
   175  
   176  // This now returns no errors due to a general fix while building the graph
   177  func TestBuiltinGraphBuilder_cbdDepNonCbd_errorsWhenVerbose(t *testing.T) {
   178  	b := &BuiltinGraphBuilder{
   179  		Root:     testModule(t, "graph-builder-cbd-non-cbd"),
   180  		Validate: true,
   181  		Verbose:  true,
   182  	}
   183  
   184  	_, err := b.Build(RootModulePath)
   185  	if err != nil {
   186  		t.Fatalf("err: %s", err)
   187  	}
   188  }
   189  
   190  func TestBuiltinGraphBuilder_multiLevelModule(t *testing.T) {
   191  	b := &BuiltinGraphBuilder{
   192  		Root:     testModule(t, "graph-builder-multi-level-module"),
   193  		Validate: true,
   194  	}
   195  
   196  	g, err := b.Build(RootModulePath)
   197  	if err != nil {
   198  		t.Fatalf("err: %s", err)
   199  	}
   200  
   201  	actual := strings.TrimSpace(g.String())
   202  	expected := strings.TrimSpace(testBuiltinGraphBuilderMultiLevelStr)
   203  	if actual != expected {
   204  		t.Fatalf("bad: %s", actual)
   205  	}
   206  }
   207  
   208  func TestBuiltinGraphBuilder_orphanDeps(t *testing.T) {
   209  	state := &State{
   210  		Modules: []*ModuleState{
   211  			&ModuleState{
   212  				Path: rootModulePath,
   213  				Resources: map[string]*ResourceState{
   214  					"aws_instance.foo": &ResourceState{
   215  						Type: "aws_instance",
   216  						Primary: &InstanceState{
   217  							ID: "foo",
   218  						},
   219  					},
   220  
   221  					"aws_instance.bar": &ResourceState{
   222  						Type:         "aws_instance",
   223  						Dependencies: []string{"aws_instance.foo"},
   224  						Primary: &InstanceState{
   225  							ID: "bar",
   226  						},
   227  					},
   228  				},
   229  			},
   230  		},
   231  	}
   232  
   233  	b := &BuiltinGraphBuilder{
   234  		Root:     testModule(t, "graph-builder-orphan-deps"),
   235  		State:    state,
   236  		Validate: true,
   237  	}
   238  
   239  	g, err := b.Build(RootModulePath)
   240  	if err != nil {
   241  		t.Fatalf("err: %s", err)
   242  	}
   243  
   244  	actual := strings.TrimSpace(g.String())
   245  	expected := strings.TrimSpace(testBuiltinGraphBuilderOrphanDepsStr)
   246  	if actual != expected {
   247  		t.Fatalf("bad: %s", actual)
   248  	}
   249  }
   250  
   251  /*
   252  TODO: This exposes a really bad bug we need to fix after we merge
   253  the f-ast-branch. This bug still exists in master.
   254  
   255  // This test tests that the graph builder properly expands modules.
   256  func TestBuiltinGraphBuilder_modules(t *testing.T) {
   257  	b := &BuiltinGraphBuilder{
   258  		Root: testModule(t, "graph-builder-modules"),
   259  	}
   260  
   261  	g, err := b.Build(RootModulePath)
   262  	if err != nil {
   263  		t.Fatalf("err: %s", err)
   264  	}
   265  
   266  	actual := strings.TrimSpace(g.String())
   267  	expected := strings.TrimSpace(testBuiltinGraphBuilderModuleStr)
   268  	if actual != expected {
   269  		t.Fatalf("bad: %s", actual)
   270  	}
   271  }
   272  */
   273  
   274  type testBasicGraphBuilderTransform struct {
   275  	V dag.Vertex
   276  }
   277  
   278  func (t *testBasicGraphBuilderTransform) Transform(g *Graph) error {
   279  	g.Add(t.V)
   280  	return nil
   281  }
   282  
   283  const testBasicGraphBuilderStr = `
   284  1
   285  `
   286  
   287  const testBuiltinGraphBuilderBasicStr = `
   288  aws_instance.db
   289    provider.aws
   290  aws_instance.web
   291    aws_instance.db
   292  provider.aws
   293  provider.aws (close)
   294    aws_instance.web
   295  `
   296  
   297  const testBuiltinGraphBuilderVerboseStr = `
   298  aws_instance.db
   299    aws_instance.db (destroy)
   300  aws_instance.db (destroy)
   301    aws_instance.web (destroy)
   302  aws_instance.web
   303    aws_instance.db
   304  aws_instance.web (destroy)
   305    provider.aws
   306  provider.aws
   307  provider.aws (close)
   308    aws_instance.web
   309  `
   310  
   311  const testBuiltinGraphBuilderMultiLevelStr = `
   312  module.foo.module.bar.output.value
   313    module.foo.module.bar.var.bar
   314    module.foo.var.foo
   315  module.foo.module.bar.plan-destroy
   316  module.foo.module.bar.var.bar
   317    module.foo.var.foo
   318  module.foo.plan-destroy
   319  module.foo.var.foo
   320  root
   321    module.foo.module.bar.output.value
   322    module.foo.module.bar.plan-destroy
   323    module.foo.module.bar.var.bar
   324    module.foo.plan-destroy
   325    module.foo.var.foo
   326  `
   327  
   328  const testBuiltinGraphBuilderOrphanDepsStr = `
   329  aws_instance.bar (orphan)
   330    provider.aws
   331  aws_instance.foo (orphan)
   332    aws_instance.bar (orphan)
   333  provider.aws
   334  provider.aws (close)
   335    aws_instance.foo (orphan)
   336  `
   337  
   338  /*
   339  TODO: Commented out this const as it's likely this needs to
   340  be updated when the TestBuiltinGraphBuilder_modules test is
   341  enabled again.
   342  const testBuiltinGraphBuilderModuleStr = `
   343  aws_instance.web
   344    aws_instance.web (destroy)
   345  aws_instance.web (destroy)
   346    aws_security_group.firewall
   347    module.consul (expanded)
   348    provider.aws
   349  aws_security_group.firewall
   350    aws_security_group.firewall (destroy)
   351  aws_security_group.firewall (destroy)
   352    provider.aws
   353  module.consul (expanded)
   354    aws_security_group.firewall
   355    provider.aws
   356  provider.aws
   357  `
   358  */