github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/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 a cycle we got when a CBD resource depends on a non-CBD
   113  // resource. This cycle shouldn't happen in the general case anymore.
   114  func TestBuiltinGraphBuilder_cbdDepNonCbd(t *testing.T) {
   115  	b := &BuiltinGraphBuilder{
   116  		Root:     testModule(t, "graph-builder-cbd-non-cbd"),
   117  		Validate: true,
   118  	}
   119  
   120  	_, err := b.Build(RootModulePath)
   121  	if err != nil {
   122  		t.Fatalf("err: %s", err)
   123  	}
   124  }
   125  
   126  func TestBuiltinGraphBuilder_cbdDepNonCbd_errorsWhenVerbose(t *testing.T) {
   127  	b := &BuiltinGraphBuilder{
   128  		Root:     testModule(t, "graph-builder-cbd-non-cbd"),
   129  		Validate: true,
   130  		Verbose:  true,
   131  	}
   132  
   133  	_, err := b.Build(RootModulePath)
   134  	if err == nil {
   135  		t.Fatalf("expected err, got none")
   136  	}
   137  }
   138  
   139  func TestBuiltinGraphBuilder_multiLevelModule(t *testing.T) {
   140  	b := &BuiltinGraphBuilder{
   141  		Root:     testModule(t, "graph-builder-multi-level-module"),
   142  		Validate: true,
   143  	}
   144  
   145  	g, err := b.Build(RootModulePath)
   146  	if err != nil {
   147  		t.Fatalf("err: %s", err)
   148  	}
   149  
   150  	actual := strings.TrimSpace(g.String())
   151  	expected := strings.TrimSpace(testBuiltinGraphBuilderMultiLevelStr)
   152  	if actual != expected {
   153  		t.Fatalf("bad: %s", actual)
   154  	}
   155  }
   156  
   157  func TestBuiltinGraphBuilder_orphanDeps(t *testing.T) {
   158  	state := &State{
   159  		Modules: []*ModuleState{
   160  			&ModuleState{
   161  				Path: rootModulePath,
   162  				Resources: map[string]*ResourceState{
   163  					"aws_instance.foo": &ResourceState{
   164  						Type: "aws_instance",
   165  						Primary: &InstanceState{
   166  							ID: "foo",
   167  						},
   168  					},
   169  
   170  					"aws_instance.bar": &ResourceState{
   171  						Type:         "aws_instance",
   172  						Dependencies: []string{"aws_instance.foo"},
   173  						Primary: &InstanceState{
   174  							ID: "bar",
   175  						},
   176  					},
   177  				},
   178  			},
   179  		},
   180  	}
   181  
   182  	b := &BuiltinGraphBuilder{
   183  		Root:     testModule(t, "graph-builder-orphan-deps"),
   184  		State:    state,
   185  		Validate: true,
   186  	}
   187  
   188  	g, err := b.Build(RootModulePath)
   189  	if err != nil {
   190  		t.Fatalf("err: %s", err)
   191  	}
   192  
   193  	actual := strings.TrimSpace(g.String())
   194  	expected := strings.TrimSpace(testBuiltinGraphBuilderOrphanDepsStr)
   195  	if actual != expected {
   196  		t.Fatalf("bad: %s", actual)
   197  	}
   198  }
   199  
   200  /*
   201  TODO: This exposes a really bad bug we need to fix after we merge
   202  the f-ast-branch. This bug still exists in master.
   203  
   204  // This test tests that the graph builder properly expands modules.
   205  func TestBuiltinGraphBuilder_modules(t *testing.T) {
   206  	b := &BuiltinGraphBuilder{
   207  		Root: testModule(t, "graph-builder-modules"),
   208  	}
   209  
   210  	g, err := b.Build(RootModulePath)
   211  	if err != nil {
   212  		t.Fatalf("err: %s", err)
   213  	}
   214  
   215  	actual := strings.TrimSpace(g.String())
   216  	expected := strings.TrimSpace(testBuiltinGraphBuilderModuleStr)
   217  	if actual != expected {
   218  		t.Fatalf("bad: %s", actual)
   219  	}
   220  }
   221  */
   222  
   223  type testBasicGraphBuilderTransform struct {
   224  	V dag.Vertex
   225  }
   226  
   227  func (t *testBasicGraphBuilderTransform) Transform(g *Graph) error {
   228  	g.Add(t.V)
   229  	return nil
   230  }
   231  
   232  const testBasicGraphBuilderStr = `
   233  1
   234  `
   235  
   236  const testBuiltinGraphBuilderBasicStr = `
   237  aws_instance.db
   238    provider.aws
   239  aws_instance.web
   240    aws_instance.db
   241  provider.aws
   242  provider.aws (close)
   243    aws_instance.web
   244  `
   245  
   246  const testBuiltinGraphBuilderVerboseStr = `
   247  aws_instance.db
   248    aws_instance.db (destroy tainted)
   249    aws_instance.db (destroy)
   250  aws_instance.db (destroy tainted)
   251    aws_instance.web (destroy tainted)
   252  aws_instance.db (destroy)
   253    aws_instance.web (destroy)
   254  aws_instance.web
   255    aws_instance.db
   256  aws_instance.web (destroy tainted)
   257    provider.aws
   258  aws_instance.web (destroy)
   259    provider.aws
   260  provider.aws
   261  provider.aws (close)
   262    aws_instance.web
   263  `
   264  
   265  const testBuiltinGraphBuilderMultiLevelStr = `
   266  module.foo.module.bar.output.value
   267    module.foo.module.bar.var.bar
   268  module.foo.module.bar.plan-destroy
   269  module.foo.module.bar.var.bar
   270    module.foo.var.foo
   271  module.foo.plan-destroy
   272  module.foo.var.foo
   273  root
   274    module.foo.module.bar.output.value
   275    module.foo.module.bar.plan-destroy
   276    module.foo.plan-destroy
   277  `
   278  
   279  const testBuiltinGraphBuilderOrphanDepsStr = `
   280  aws_instance.bar (orphan)
   281    provider.aws
   282  aws_instance.foo (orphan)
   283    aws_instance.bar (orphan)
   284  provider.aws
   285  provider.aws (close)
   286    aws_instance.foo (orphan)
   287  `
   288  
   289  /*
   290  TODO: Commented out this const as it's likely this needs to
   291  be updated when the TestBuiltinGraphBuilder_modules test is
   292  enabled again.
   293  const testBuiltinGraphBuilderModuleStr = `
   294  aws_instance.web
   295    aws_instance.web (destroy)
   296  aws_instance.web (destroy)
   297    aws_security_group.firewall
   298    module.consul (expanded)
   299    provider.aws
   300  aws_security_group.firewall
   301    aws_security_group.firewall (destroy)
   302  aws_security_group.firewall (destroy)
   303    provider.aws
   304  module.consul (expanded)
   305    aws_security_group.firewall
   306    provider.aws
   307  provider.aws
   308  `
   309  */