From 4c474fe0291f2605d2e39da18bdc992734687e17 Mon Sep 17 00:00:00 2001 From: Laura Brehm Date: Tue, 6 Sep 2022 21:12:43 +0200 Subject: [PATCH] Add unit tests to graph building logic in `dependencies.go` Signed-off-by: Laura Brehm --- pkg/compose/dependencies_test.go | 180 +++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/pkg/compose/dependencies_test.go b/pkg/compose/dependencies_test.go index 61bf0fd9..baaa98ce 100644 --- a/pkg/compose/dependencies_test.go +++ b/pkg/compose/dependencies_test.go @@ -18,10 +18,12 @@ package compose import ( "context" + "fmt" "testing" "github.com/compose-spec/compose-go/types" "github.com/stretchr/testify/require" + "gotest.tools/assert" ) var project = types.Project{ @@ -69,3 +71,181 @@ func TestInDependencyReverseDownCommandOrder(t *testing.T) { require.NoError(t, err, "Error during iteration") require.Equal(t, []string{"test1", "test2", "test3"}, order) } + +func TestBuildGraph(t *testing.T) { + testCases := []struct { + desc string + services types.Services + expectedVertices map[string]*Vertex + }{ + { + desc: "builds graph with single service", + services: types.Services{ + { + Name: "test", + DependsOn: types.DependsOnConfig{}, + }, + }, + expectedVertices: map[string]*Vertex{ + "test": { + Key: "test", + Service: "test", + Status: ServiceStopped, + Children: map[string]*Vertex{}, + Parents: map[string]*Vertex{}, + }, + }, + }, + { + desc: "builds graph with two separate services", + services: types.Services{ + { + Name: "test", + DependsOn: types.DependsOnConfig{}, + }, + { + Name: "another", + DependsOn: types.DependsOnConfig{}, + }, + }, + expectedVertices: map[string]*Vertex{ + "test": { + Key: "test", + Service: "test", + Status: ServiceStopped, + Children: map[string]*Vertex{}, + Parents: map[string]*Vertex{}, + }, + "another": { + Key: "another", + Service: "another", + Status: ServiceStopped, + Children: map[string]*Vertex{}, + Parents: map[string]*Vertex{}, + }, + }, + }, + { + desc: "builds graph with a service and a dependency", + services: types.Services{ + { + Name: "test", + DependsOn: types.DependsOnConfig{ + "another": types.ServiceDependency{}, + }, + }, + { + Name: "another", + DependsOn: types.DependsOnConfig{}, + }, + }, + expectedVertices: map[string]*Vertex{ + "test": { + Key: "test", + Service: "test", + Status: ServiceStopped, + Children: map[string]*Vertex{ + "another": {}, + }, + Parents: map[string]*Vertex{}, + }, + "another": { + Key: "another", + Service: "another", + Status: ServiceStopped, + Children: map[string]*Vertex{}, + Parents: map[string]*Vertex{ + "test": {}, + }, + }, + }, + }, + { + desc: "builds graph with multiple dependency levels", + services: types.Services{ + { + Name: "test", + DependsOn: types.DependsOnConfig{ + "another": types.ServiceDependency{}, + }, + }, + { + Name: "another", + DependsOn: types.DependsOnConfig{ + "another_dep": types.ServiceDependency{}, + }, + }, + { + Name: "another_dep", + DependsOn: types.DependsOnConfig{}, + }, + }, + expectedVertices: map[string]*Vertex{ + "test": { + Key: "test", + Service: "test", + Status: ServiceStopped, + Children: map[string]*Vertex{ + "another": {}, + }, + Parents: map[string]*Vertex{}, + }, + "another": { + Key: "another", + Service: "another", + Status: ServiceStopped, + Children: map[string]*Vertex{ + "another_dep": {}, + }, + Parents: map[string]*Vertex{ + "test": {}, + }, + }, + "another_dep": { + Key: "another_dep", + Service: "another_dep", + Status: ServiceStopped, + Children: map[string]*Vertex{}, + Parents: map[string]*Vertex{ + "another": {}, + }, + }, + }, + }, + } + for _, tC := range testCases { + t.Run(tC.desc, func(t *testing.T) { + project := types.Project{ + Services: tC.services, + } + + graph, err := NewGraph(project.Services, ServiceStopped) + assert.NilError(t, err, fmt.Sprintf("failed to build graph for: %s", tC.desc)) + + for k, vertex := range graph.Vertices { + expected, ok := tC.expectedVertices[k] + assert.Equal(t, true, ok) + assert.Equal(t, true, isVertexEqual(*expected, *vertex)) + } + }) + } +} + +func isVertexEqual(a, b Vertex) bool { + childrenEquality := true + for c := range a.Children { + if _, ok := b.Children[c]; !ok { + childrenEquality = false + } + } + parentEquality := true + for p := range a.Parents { + if _, ok := b.Parents[p]; !ok { + parentEquality = false + } + } + return a.Key == b.Key && + a.Service == b.Service && + childrenEquality && + parentEquality +}