github.com/markdia/terraform@v0.5.1-0.20150508012022-f1ae920aa970/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.Connect(BasicEdge(3, 2))
   230  	g.Connect(BasicEdge(3, 1))
   231  
   232  	var visits []Vertex
   233  	var lock sync.Mutex
   234  	err := g.Walk(func(v Vertex) error {
   235  		lock.Lock()
   236  		defer lock.Unlock()
   237  
   238  		if v == 2 {
   239  			return fmt.Errorf("error")
   240  		}
   241  
   242  		visits = append(visits, v)
   243  		return nil
   244  	})
   245  	if err == nil {
   246  		t.Fatal("should error")
   247  	}
   248  
   249  	expected := [][]Vertex{
   250  		{1},
   251  	}
   252  	for _, e := range expected {
   253  		if reflect.DeepEqual(visits, e) {
   254  			return
   255  		}
   256  	}
   257  
   258  	t.Fatalf("bad: %#v", visits)
   259  }
   260  
   261  const testGraphTransReductionStr = `
   262  1
   263    2
   264  2
   265    3
   266  3
   267  `
   268  
   269  const testGraphTransReductionMoreStr = `
   270  1
   271    2
   272  2
   273    3
   274  3
   275    4
   276  4
   277  `