github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/dag/dag_test.go (about)

     1  package dag
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"sync"
     8  	"testing"
     9  )
    10  
    11  func TestAcyclicGraphRoot(t *testing.T) {
    12  	var g AcyclicGraph
    13  	g.Add(1)
    14  	g.Add(2)
    15  	g.Add(3)
    16  	g.Connect(BasicEdge(3, 2))
    17  	g.Connect(BasicEdge(3, 1))
    18  
    19  	if root, err := g.Root(); err != nil {
    20  		t.Fatalf("err: %s", err)
    21  	} else if root != 3 {
    22  		t.Fatalf("bad: %#v", root)
    23  	}
    24  }
    25  
    26  func TestAcyclicGraphRoot_cycle(t *testing.T) {
    27  	var g AcyclicGraph
    28  	g.Add(1)
    29  	g.Add(2)
    30  	g.Add(3)
    31  	g.Connect(BasicEdge(1, 2))
    32  	g.Connect(BasicEdge(2, 3))
    33  	g.Connect(BasicEdge(3, 1))
    34  
    35  	if _, err := g.Root(); err == nil {
    36  		t.Fatal("should error")
    37  	}
    38  }
    39  
    40  func TestAcyclicGraphRoot_multiple(t *testing.T) {
    41  	var g AcyclicGraph
    42  	g.Add(1)
    43  	g.Add(2)
    44  	g.Add(3)
    45  	g.Connect(BasicEdge(3, 2))
    46  
    47  	if _, err := g.Root(); err == nil {
    48  		t.Fatal("should error")
    49  	}
    50  }
    51  
    52  func TestAyclicGraphTransReduction(t *testing.T) {
    53  	var g AcyclicGraph
    54  	g.Add(1)
    55  	g.Add(2)
    56  	g.Add(3)
    57  	g.Connect(BasicEdge(1, 2))
    58  	g.Connect(BasicEdge(1, 3))
    59  	g.Connect(BasicEdge(2, 3))
    60  	g.TransitiveReduction()
    61  
    62  	actual := strings.TrimSpace(g.String())
    63  	expected := strings.TrimSpace(testGraphTransReductionStr)
    64  	if actual != expected {
    65  		t.Fatalf("bad: %s", actual)
    66  	}
    67  }
    68  
    69  func TestAyclicGraphTransReduction_more(t *testing.T) {
    70  	var g AcyclicGraph
    71  	g.Add(1)
    72  	g.Add(2)
    73  	g.Add(3)
    74  	g.Add(4)
    75  	g.Connect(BasicEdge(1, 2))
    76  	g.Connect(BasicEdge(1, 3))
    77  	g.Connect(BasicEdge(1, 4))
    78  	g.Connect(BasicEdge(2, 3))
    79  	g.Connect(BasicEdge(2, 4))
    80  	g.Connect(BasicEdge(3, 4))
    81  	g.TransitiveReduction()
    82  
    83  	actual := strings.TrimSpace(g.String())
    84  	expected := strings.TrimSpace(testGraphTransReductionMoreStr)
    85  	if actual != expected {
    86  		t.Fatalf("bad: %s", actual)
    87  	}
    88  }
    89  
    90  func TestAcyclicGraphValidate(t *testing.T) {
    91  	var g AcyclicGraph
    92  	g.Add(1)
    93  	g.Add(2)
    94  	g.Add(3)
    95  	g.Connect(BasicEdge(3, 2))
    96  	g.Connect(BasicEdge(3, 1))
    97  
    98  	if err := g.Validate(); err != nil {
    99  		t.Fatalf("err: %s", err)
   100  	}
   101  }
   102  
   103  func TestAcyclicGraphValidate_cycle(t *testing.T) {
   104  	var g AcyclicGraph
   105  	g.Add(1)
   106  	g.Add(2)
   107  	g.Add(3)
   108  	g.Connect(BasicEdge(3, 2))
   109  	g.Connect(BasicEdge(3, 1))
   110  	g.Connect(BasicEdge(1, 2))
   111  	g.Connect(BasicEdge(2, 1))
   112  
   113  	if err := g.Validate(); err == nil {
   114  		t.Fatal("should error")
   115  	}
   116  }
   117  
   118  func TestAcyclicGraphValidate_cycleSelf(t *testing.T) {
   119  	var g AcyclicGraph
   120  	g.Add(1)
   121  	g.Add(2)
   122  	g.Connect(BasicEdge(1, 1))
   123  
   124  	if err := g.Validate(); err == nil {
   125  		t.Fatal("should error")
   126  	}
   127  }
   128  
   129  func TestAcyclicGraphAncestors(t *testing.T) {
   130  	var g AcyclicGraph
   131  	g.Add(1)
   132  	g.Add(2)
   133  	g.Add(3)
   134  	g.Add(4)
   135  	g.Add(5)
   136  	g.Connect(BasicEdge(0, 1))
   137  	g.Connect(BasicEdge(1, 2))
   138  	g.Connect(BasicEdge(2, 3))
   139  	g.Connect(BasicEdge(3, 4))
   140  	g.Connect(BasicEdge(4, 5))
   141  
   142  	actual, err := g.Ancestors(2)
   143  	if err != nil {
   144  		t.Fatalf("err: %#v", err)
   145  	}
   146  
   147  	expected := []Vertex{3, 4, 5}
   148  
   149  	if actual.Len() != len(expected) {
   150  		t.Fatalf("bad length! expected %#v to have len %d", actual, len(expected))
   151  	}
   152  
   153  	for _, e := range expected {
   154  		if !actual.Include(e) {
   155  			t.Fatalf("expected: %#v to include: %#v", expected, actual)
   156  		}
   157  	}
   158  }
   159  
   160  func TestAcyclicGraphDescendents(t *testing.T) {
   161  	var g AcyclicGraph
   162  	g.Add(1)
   163  	g.Add(2)
   164  	g.Add(3)
   165  	g.Add(4)
   166  	g.Add(5)
   167  	g.Connect(BasicEdge(0, 1))
   168  	g.Connect(BasicEdge(1, 2))
   169  	g.Connect(BasicEdge(2, 3))
   170  	g.Connect(BasicEdge(3, 4))
   171  	g.Connect(BasicEdge(4, 5))
   172  
   173  	actual, err := g.Descendents(2)
   174  	if err != nil {
   175  		t.Fatalf("err: %#v", err)
   176  	}
   177  
   178  	expected := []Vertex{0, 1}
   179  
   180  	if actual.Len() != len(expected) {
   181  		t.Fatalf("bad length! expected %#v to have len %d", actual, len(expected))
   182  	}
   183  
   184  	for _, e := range expected {
   185  		if !actual.Include(e) {
   186  			t.Fatalf("expected: %#v to include: %#v", expected, actual)
   187  		}
   188  	}
   189  }
   190  
   191  func TestAcyclicGraphWalk(t *testing.T) {
   192  	var g AcyclicGraph
   193  	g.Add(1)
   194  	g.Add(2)
   195  	g.Add(3)
   196  	g.Connect(BasicEdge(3, 2))
   197  	g.Connect(BasicEdge(3, 1))
   198  
   199  	var visits []Vertex
   200  	var lock sync.Mutex
   201  	err := g.Walk(func(v Vertex) error {
   202  		lock.Lock()
   203  		defer lock.Unlock()
   204  		visits = append(visits, v)
   205  		return nil
   206  	})
   207  	if err != nil {
   208  		t.Fatalf("err: %s", err)
   209  	}
   210  
   211  	expected := [][]Vertex{
   212  		{1, 2, 3},
   213  		{2, 1, 3},
   214  	}
   215  	for _, e := range expected {
   216  		if reflect.DeepEqual(visits, e) {
   217  			return
   218  		}
   219  	}
   220  
   221  	t.Fatalf("bad: %#v", visits)
   222  }
   223  
   224  func TestAcyclicGraphWalk_error(t *testing.T) {
   225  	var g AcyclicGraph
   226  	g.Add(1)
   227  	g.Add(2)
   228  	g.Add(3)
   229  	g.Add(4)
   230  	g.Connect(BasicEdge(4, 3))
   231  	g.Connect(BasicEdge(3, 2))
   232  	g.Connect(BasicEdge(2, 1))
   233  
   234  	var visits []Vertex
   235  	var lock sync.Mutex
   236  	err := g.Walk(func(v Vertex) error {
   237  		lock.Lock()
   238  		defer lock.Unlock()
   239  
   240  		if v == 2 {
   241  			return fmt.Errorf("error")
   242  		}
   243  
   244  		visits = append(visits, v)
   245  		return nil
   246  	})
   247  	if err == nil {
   248  		t.Fatal("should error")
   249  	}
   250  
   251  	expected := [][]Vertex{
   252  		{1},
   253  	}
   254  	for _, e := range expected {
   255  		if reflect.DeepEqual(visits, e) {
   256  			return
   257  		}
   258  	}
   259  
   260  	t.Fatalf("bad: %#v", visits)
   261  }
   262  
   263  const testGraphTransReductionStr = `
   264  1
   265    2
   266  2
   267    3
   268  3
   269  `
   270  
   271  const testGraphTransReductionMoreStr = `
   272  1
   273    2
   274  2
   275    3
   276  3
   277    4
   278  4
   279  `