github.com/pbthorste/terraform@v0.8.6-0.20170127005045-deb56bd93da2/terraform/graph_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 TestGraphAdd(t *testing.T) {
    12  	// Test Add since we override it and want to make sure we don't break it.
    13  	var g Graph
    14  	g.Add(42)
    15  	g.Add(84)
    16  
    17  	actual := strings.TrimSpace(g.String())
    18  	expected := strings.TrimSpace(testGraphAddStr)
    19  	if actual != expected {
    20  		t.Fatalf("bad: %s", actual)
    21  	}
    22  }
    23  
    24  func TestGraphConnectDependent(t *testing.T) {
    25  	var g Graph
    26  	g.Add(&testGraphDependable{VertexName: "a"})
    27  	b := g.Add(&testGraphDependable{
    28  		VertexName:      "b",
    29  		DependentOnMock: []string{"a"},
    30  	})
    31  
    32  	if missing := g.ConnectDependent(b); len(missing) > 0 {
    33  		t.Fatalf("bad: %#v", missing)
    34  	}
    35  
    36  	actual := strings.TrimSpace(g.String())
    37  	expected := strings.TrimSpace(testGraphConnectDepsStr)
    38  	if actual != expected {
    39  		t.Fatalf("bad: %s", actual)
    40  	}
    41  }
    42  
    43  func TestGraphReplace_DependableWithNonDependable(t *testing.T) {
    44  	var g Graph
    45  	a := g.Add(&testGraphDependable{VertexName: "a"})
    46  	b := g.Add(&testGraphDependable{
    47  		VertexName:      "b",
    48  		DependentOnMock: []string{"a"},
    49  	})
    50  	newA := "non-dependable-a"
    51  
    52  	if missing := g.ConnectDependent(b); len(missing) > 0 {
    53  		t.Fatalf("bad: %#v", missing)
    54  	}
    55  
    56  	if !g.Replace(a, newA) {
    57  		t.Fatalf("failed to replace")
    58  	}
    59  
    60  	c := g.Add(&testGraphDependable{
    61  		VertexName:      "c",
    62  		DependentOnMock: []string{"a"},
    63  	})
    64  
    65  	// This should fail by reporting missing, since a node with dependable
    66  	// name "a" is no longer in the graph.
    67  	missing := g.ConnectDependent(c)
    68  	expected := []string{"a"}
    69  	if !reflect.DeepEqual(expected, missing) {
    70  		t.Fatalf("expected: %#v, got: %#v", expected, missing)
    71  	}
    72  }
    73  
    74  func TestGraphWalk_panicWrap(t *testing.T) {
    75  	var g Graph
    76  
    77  	// Add our crasher
    78  	v := &testGraphSubPath{
    79  		PathFn: func() []string {
    80  			panic("yo")
    81  		},
    82  	}
    83  	g.Add(v)
    84  
    85  	err := g.Walk(GraphWalkerPanicwrap(new(NullGraphWalker)))
    86  	if err == nil {
    87  		t.Fatal("should error")
    88  	}
    89  }
    90  
    91  // testGraphContains is an assertion helper that tests that a node is
    92  // contained in the graph.
    93  func testGraphContains(t *testing.T, g *Graph, name string) {
    94  	for _, v := range g.Vertices() {
    95  		if dag.VertexName(v) == name {
    96  			return
    97  		}
    98  	}
    99  
   100  	t.Fatalf(
   101  		"Expected %q in:\n\n%s",
   102  		name, g.String())
   103  }
   104  
   105  // testGraphnotContains is an assertion helper that tests that a node is
   106  // NOT contained in the graph.
   107  func testGraphNotContains(t *testing.T, g *Graph, name string) {
   108  	for _, v := range g.Vertices() {
   109  		if dag.VertexName(v) == name {
   110  			t.Fatalf(
   111  				"Expected %q to NOT be in:\n\n%s",
   112  				name, g.String())
   113  		}
   114  	}
   115  }
   116  
   117  // testGraphHappensBefore is an assertion helper that tests that node
   118  // A (dag.VertexName value) happens before node B.
   119  func testGraphHappensBefore(t *testing.T, g *Graph, A, B string) {
   120  	// Find the B vertex
   121  	var vertexB dag.Vertex
   122  	for _, v := range g.Vertices() {
   123  		if dag.VertexName(v) == B {
   124  			vertexB = v
   125  			break
   126  		}
   127  	}
   128  	if vertexB == nil {
   129  		t.Fatalf(
   130  			"Expected %q before %q. Couldn't find %q in:\n\n%s",
   131  			A, B, B, g.String())
   132  	}
   133  
   134  	// Look at ancestors
   135  	deps, err := g.Ancestors(vertexB)
   136  	if err != nil {
   137  		t.Fatalf("Error: %s in graph:\n\n%s", err, g.String())
   138  	}
   139  
   140  	// Make sure B is in there
   141  	for _, v := range deps.List() {
   142  		if dag.VertexName(v) == A {
   143  			// Success
   144  			return
   145  		}
   146  	}
   147  
   148  	t.Fatalf(
   149  		"Expected %q before %q in:\n\n%s",
   150  		A, B, g.String())
   151  }
   152  
   153  type testGraphSubPath struct {
   154  	PathFn func() []string
   155  }
   156  
   157  func (v *testGraphSubPath) Path() []string { return v.PathFn() }
   158  
   159  type testGraphDependable struct {
   160  	VertexName      string
   161  	DependentOnMock []string
   162  }
   163  
   164  func (v *testGraphDependable) Name() string {
   165  	return v.VertexName
   166  }
   167  
   168  func (v *testGraphDependable) DependableName() []string {
   169  	return []string{v.VertexName}
   170  }
   171  
   172  func (v *testGraphDependable) DependentOn() []string {
   173  	return v.DependentOnMock
   174  }
   175  
   176  const testGraphAddStr = `
   177  42
   178  84
   179  `
   180  
   181  const testGraphConnectDepsStr = `
   182  a
   183  b
   184    a
   185  `