github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/release/dependency/graph_test.go (about)

     1  package dependency_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/helmwave/helmwave/pkg/release/dependency"
     8  	"github.com/stretchr/testify/suite"
     9  )
    10  
    11  type GraphTestSuite struct {
    12  	suite.Suite
    13  }
    14  
    15  func (s *GraphTestSuite) TestNewNode() {
    16  	key := "1"
    17  	data := "123"
    18  
    19  	graph := dependency.NewGraph[string, string]()
    20  	s.Require().NoError(graph.NewNode(key, data))
    21  
    22  	s.Require().Len(graph.Nodes, 1)
    23  	s.Require().Contains(graph.Nodes, key)
    24  	s.Require().Equal(graph.Nodes[key].Data, data)
    25  	s.Require().False(graph.Nodes[key].IsDone())
    26  	s.Require().True(graph.Nodes[key].IsReady())
    27  
    28  	s.Require().NoError(graph.Build())
    29  }
    30  
    31  func (s *GraphTestSuite) TestDuplicateNode() {
    32  	key := "1"
    33  
    34  	graph := dependency.NewGraph[string, string]()
    35  
    36  	s.Require().NoError(graph.NewNode(key, "123"))
    37  	s.Require().Error(graph.NewNode(key, "321"))
    38  	s.Require().Len(graph.Nodes, 1)
    39  
    40  	s.Require().NoError(graph.Build())
    41  }
    42  
    43  // 1 -> 3 -> 4
    44  // 2 /
    45  func (s *GraphTestSuite) TestDependencies() {
    46  	graph := dependency.NewGraph[string, string]()
    47  
    48  	s.Require().NoError(graph.NewNode("1", "1"))
    49  	s.Require().NoError(graph.NewNode("2", "2"))
    50  	s.Require().NoError(graph.NewNode("3", "3"))
    51  	s.Require().NoError(graph.NewNode("4", "4"))
    52  
    53  	graph.AddDependency("3", "1")
    54  	graph.AddDependency("3", "2")
    55  	graph.AddDependency("4", "3")
    56  
    57  	s.Require().NoError(graph.Build())
    58  
    59  	ch := graph.Run()
    60  
    61  	s.Require().NotNil(ch)
    62  	s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond)
    63  	s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond)
    64  	d1, d2 := <-ch, <-ch
    65  	s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data})
    66  	d1.SetSucceeded()
    67  	d2.SetSucceeded()
    68  
    69  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
    70  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
    71  	d := <-ch
    72  	s.Require().Equal("3", d.Data)
    73  	d.SetSucceeded()
    74  
    75  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
    76  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
    77  	d = <-ch
    78  	s.Require().Equal("4", d.Data)
    79  	d.SetSucceeded()
    80  
    81  	s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond)
    82  }
    83  
    84  func (s *GraphTestSuite) TestFailedDependencies() {
    85  	graph := dependency.NewGraph[string, string]()
    86  
    87  	s.Require().NoError(graph.NewNode("1", "1"))
    88  	s.Require().NoError(graph.NewNode("2", "2"))
    89  	s.Require().NoError(graph.NewNode("3", "3"))
    90  	s.Require().NoError(graph.NewNode("4", "4"))
    91  
    92  	graph.AddDependency("3", "1")
    93  	graph.AddDependency("3", "2")
    94  	graph.AddDependency("4", "3")
    95  
    96  	s.Require().NoError(graph.Build())
    97  
    98  	ch := graph.Run()
    99  
   100  	s.Require().NotNil(ch)
   101  	s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond)
   102  	s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond)
   103  	d1, d2 := <-ch, <-ch
   104  	s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data})
   105  	d1.SetSucceeded()
   106  	d2.SetFailed()
   107  
   108  	s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond)
   109  }
   110  
   111  func (s *GraphTestSuite) TestCycles() {
   112  	graph := dependency.NewGraph[string, string]()
   113  
   114  	s.Require().NoError(graph.NewNode("1", "1"))
   115  	s.Require().NoError(graph.NewNode("2", "2"))
   116  
   117  	graph.AddDependency("1", "2")
   118  	graph.AddDependency("2", "1")
   119  
   120  	s.Require().Error(graph.Build())
   121  }
   122  
   123  // 1 -> 3 -> 4
   124  // 2 /
   125  // Reversed
   126  // 4 -> 3 -> 1
   127  //
   128  //	\-> 2
   129  func (s *GraphTestSuite) TestReverse() {
   130  	graph := dependency.NewGraph[string, string]()
   131  
   132  	s.Require().NoError(graph.NewNode("1", "1"))
   133  	s.Require().NoError(graph.NewNode("2", "2"))
   134  	s.Require().NoError(graph.NewNode("3", "3"))
   135  	s.Require().NoError(graph.NewNode("4", "4"))
   136  
   137  	graph.AddDependency("3", "1")
   138  	graph.AddDependency("3", "2")
   139  	graph.AddDependency("4", "3")
   140  
   141  	s.Require().NoError(graph.Build())
   142  	graph, err := graph.Reverse()
   143  	s.Require().NoError(err)
   144  
   145  	ch := graph.Run()
   146  
   147  	s.Require().NotNil(ch)
   148  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
   149  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
   150  	d := <-ch
   151  	s.Require().Equal("4", d.Data)
   152  	d.SetSucceeded()
   153  
   154  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
   155  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
   156  	d = <-ch
   157  	s.Require().Equal("3", d.Data)
   158  	d.SetSucceeded()
   159  
   160  	s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond)
   161  	s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond)
   162  	d1, d2 := <-ch, <-ch
   163  	s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data})
   164  	d1.SetSucceeded()
   165  	d2.SetSucceeded()
   166  
   167  	s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond)
   168  }
   169  
   170  func (s *GraphTestSuite) TestReverseFailedDependencies() {
   171  	graph := dependency.NewGraph[string, string]()
   172  
   173  	s.Require().NoError(graph.NewNode("1", "1"))
   174  	s.Require().NoError(graph.NewNode("2", "2"))
   175  	s.Require().NoError(graph.NewNode("3", "3"))
   176  	s.Require().NoError(graph.NewNode("4", "4"))
   177  
   178  	graph.AddDependency("3", "1")
   179  	graph.AddDependency("3", "2")
   180  	graph.AddDependency("4", "3")
   181  
   182  	s.Require().NoError(graph.Build())
   183  	graph, err := graph.Reverse()
   184  	s.Require().NoError(err)
   185  
   186  	ch := graph.Run()
   187  
   188  	s.Require().NotNil(ch)
   189  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
   190  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
   191  	d := <-ch
   192  	s.Require().Equal("4", d.Data)
   193  	d.SetSucceeded()
   194  
   195  	s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond)
   196  	s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond)
   197  	d = <-ch
   198  	s.Require().Equal("3", d.Data)
   199  	d.SetFailed()
   200  
   201  	s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond)
   202  }
   203  
   204  func TestGraphTestSuite(t *testing.T) {
   205  	t.Parallel()
   206  	suite.Run(t, new(GraphTestSuite))
   207  }