snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
429
server/pkg/envoy/graph_test.go
Normal file
429
server/pkg/envoy/graph_test.go
Normal file
@@ -0,0 +1,429 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoy/resource"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGraph_Walk(t *testing.T) {
|
||||
req := require.New(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("simple node link; a -> b", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
b := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id2"},
|
||||
refs: nil,
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
b,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
g.invert()
|
||||
|
||||
s, err := g.Next(ctx)
|
||||
req.Equal(b, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.Next(ctx)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
})
|
||||
|
||||
t.Run("cyclic node link; a -> b -> a", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
b := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id2"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
b,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
g.invert()
|
||||
|
||||
s, err := g.Next(ctx)
|
||||
req.Equal(a, s.Res)
|
||||
req.True(s.Conflicting)
|
||||
|
||||
s, err = g.Next(ctx)
|
||||
req.Equal(b, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.Next(ctx)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
})
|
||||
|
||||
t.Run("self-cycle; a -> a", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
g.invert()
|
||||
|
||||
s, err := g.Next(ctx)
|
||||
req.Equal(a, s.Res)
|
||||
req.True(s.Conflicting)
|
||||
|
||||
s, err = g.Next(ctx)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGraph_WalkFlags(t *testing.T) {
|
||||
req := require.New(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("simple node link; a -> b -> c -> c", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
b := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id2"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
|
||||
}
|
||||
c := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id3"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
|
||||
s, err := g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(c, s.Res)
|
||||
req.True(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(b, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(c, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Nil(s)
|
||||
})
|
||||
|
||||
t.Run("simple node link; a -> b -> c -> d -> b; a -> b -> e", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
b := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id2"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5"}}},
|
||||
}
|
||||
c := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id3"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4"}}},
|
||||
}
|
||||
d := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id4"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
e := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id5"},
|
||||
refs: nil,
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
|
||||
s, err := g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(e, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(b, s.Res)
|
||||
req.True(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(d, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(c, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(b, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Nil(s)
|
||||
})
|
||||
|
||||
t.Run("simple node link; a -> b -> c -> d -> b; a -> b -> c -> e -> b", func(t *testing.T) {
|
||||
bl := NewBuilder()
|
||||
|
||||
a := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id1"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
b := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id2"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
|
||||
}
|
||||
c := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id3"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4"}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5"}}},
|
||||
}
|
||||
d := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id4"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
e := &testResource{
|
||||
resType: "test:resource:1:",
|
||||
identifiers: resource.Identifiers{"id5"},
|
||||
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
|
||||
}
|
||||
|
||||
rr := []resource.Interface{
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
}
|
||||
|
||||
g, err := bl.Build(ctx, rr...)
|
||||
req.NoError(err)
|
||||
|
||||
s, err := g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(b, s.Res)
|
||||
req.True(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(a, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(d, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(e, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(c, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Equal(b, s.Res)
|
||||
req.False(s.Conflicting)
|
||||
|
||||
s, err = g.NextInverted(ctx)
|
||||
req.NoError(err)
|
||||
req.Nil(s)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGraph_Utilities(t *testing.T) {
|
||||
req := require.New(t)
|
||||
|
||||
t.Run("adding & removing nodes", func(t *testing.T) {
|
||||
g := newGraph()
|
||||
n1 := newNode(nil)
|
||||
n2 := newNode(nil)
|
||||
|
||||
// Adding nodes
|
||||
g.addNode(n1, n2)
|
||||
req.Len(g.nn, 2)
|
||||
req.Equal(n1, g.nn[0])
|
||||
req.Equal(n2, g.nn[1])
|
||||
|
||||
// Dependencies
|
||||
g.addChild(n1, n2)
|
||||
g.addParent(n2, n1)
|
||||
req.True(g.childNodes(n1).has(n2))
|
||||
req.True(g.parentNodes(n2).has(n1))
|
||||
|
||||
// Removing nodes
|
||||
g.removeNode(n1, n2)
|
||||
req.False(g.childNodes(n1).has(n2))
|
||||
req.False(g.parentNodes(n2).has(n1))
|
||||
})
|
||||
|
||||
t.Run("inverted graph", func(t *testing.T) {
|
||||
g := newGraph()
|
||||
n1 := newNode(nil)
|
||||
n2 := newNode(nil)
|
||||
|
||||
// Adding nodes
|
||||
g.addNode(n1, n2)
|
||||
req.Len(g.nn, 2)
|
||||
req.Equal(n1, g.nn[0])
|
||||
req.Equal(n2, g.nn[1])
|
||||
|
||||
// Dependencies
|
||||
g.addChild(n1, n2)
|
||||
g.addParent(n2, n1)
|
||||
g.invert()
|
||||
req.True(g.parentNodes(n1).has(n2))
|
||||
req.True(g.childNodes(n2).has(n1))
|
||||
})
|
||||
|
||||
t.Run("inverted child dependencies", func(t *testing.T) {
|
||||
g := newGraph()
|
||||
n1 := newNode(nil)
|
||||
n2 := newNode(nil)
|
||||
n3 := newNode(nil)
|
||||
|
||||
g.addNode(n1, n2, n3)
|
||||
|
||||
g.addChild(n1, n2)
|
||||
g.invert()
|
||||
g.addChild(n1, n3)
|
||||
req.Equal(n2, n1.cc[0])
|
||||
req.Equal(n3, n1.pp[0])
|
||||
|
||||
g.removeChild(n1, n3)
|
||||
req.Len(n1.pp, 0)
|
||||
})
|
||||
|
||||
t.Run("inverted parent dependencies", func(t *testing.T) {
|
||||
g := newGraph()
|
||||
n1 := newNode(nil)
|
||||
n2 := newNode(nil)
|
||||
n3 := newNode(nil)
|
||||
|
||||
g.addNode(n1, n2, n3)
|
||||
|
||||
g.addParent(n1, n2)
|
||||
g.invert()
|
||||
g.addParent(n1, n3)
|
||||
req.Equal(n2, n1.pp[0])
|
||||
req.Equal(n3, n1.cc[0])
|
||||
|
||||
g.removeParent(n1, n3)
|
||||
req.Len(n1.cc, 0)
|
||||
})
|
||||
|
||||
// This one is just for codecoverage; the logic is nothing
|
||||
t.Run("remove all child/parent nodes", func(t *testing.T) {
|
||||
g := newGraph()
|
||||
n1 := newNode(nil)
|
||||
n2 := newNode(nil)
|
||||
|
||||
g.addNode(n1, n2)
|
||||
g.addChild(n1, n2)
|
||||
g.addParent(n1, n2)
|
||||
|
||||
g.removeChild(n1)
|
||||
g.removeParent(n1)
|
||||
req.Len(n1.cc, 0)
|
||||
req.Len(n1.pp, 0)
|
||||
|
||||
// Inverted graph
|
||||
g.addChild(n1, n2)
|
||||
g.addParent(n1, n2)
|
||||
g.invert()
|
||||
|
||||
g.removeChild(n1)
|
||||
g.removeParent(n1)
|
||||
req.Len(n1.cc, 0)
|
||||
req.Len(n1.pp, 0)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user