github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/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 TestAcyclicGraphWalk(t *testing.T) {
   130  	var g AcyclicGraph
   131  	g.Add(1)
   132  	g.Add(2)
   133  	g.Add(3)
   134  	g.Connect(BasicEdge(3, 2))
   135  	g.Connect(BasicEdge(3, 1))
   136  
   137  	var visits []Vertex
   138  	var lock sync.Mutex
   139  	err := g.Walk(func(v Vertex) error {
   140  		lock.Lock()
   141  		defer lock.Unlock()
   142  		visits = append(visits, v)
   143  		return nil
   144  	})
   145  	if err != nil {
   146  		t.Fatalf("err: %s", err)
   147  	}
   148  
   149  	expected := [][]Vertex{
   150  		{1, 2, 3},
   151  		{2, 1, 3},
   152  	}
   153  	for _, e := range expected {
   154  		if reflect.DeepEqual(visits, e) {
   155  			return
   156  		}
   157  	}
   158  
   159  	t.Fatalf("bad: %#v", visits)
   160  }
   161  
   162  func TestAcyclicGraphWalk_error(t *testing.T) {
   163  	var g AcyclicGraph
   164  	g.Add(1)
   165  	g.Add(2)
   166  	g.Add(3)
   167  	g.Connect(BasicEdge(3, 2))
   168  	g.Connect(BasicEdge(3, 1))
   169  
   170  	var visits []Vertex
   171  	var lock sync.Mutex
   172  	err := g.Walk(func(v Vertex) error {
   173  		lock.Lock()
   174  		defer lock.Unlock()
   175  
   176  		if v == 2 {
   177  			return fmt.Errorf("error")
   178  		}
   179  
   180  		visits = append(visits, v)
   181  		return nil
   182  	})
   183  	if err == nil {
   184  		t.Fatal("should error")
   185  	}
   186  
   187  	expected := [][]Vertex{
   188  		{1},
   189  	}
   190  	for _, e := range expected {
   191  		if reflect.DeepEqual(visits, e) {
   192  			return
   193  		}
   194  	}
   195  
   196  	t.Fatalf("bad: %#v", visits)
   197  }
   198  
   199  const testGraphTransReductionStr = `
   200  1
   201    2
   202  2
   203    3
   204  3
   205  `
   206  
   207  const testGraphTransReductionMoreStr = `
   208  1
   209    2
   210  2
   211    3
   212  3
   213    4
   214  4
   215  `