From 593235848a3e19b8170b3713e7dc6911b0337720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=C5=BE=20Jerman?= Date: Mon, 30 Nov 2020 18:25:42 +0100 Subject: [PATCH] Add tests for reference constraints --- tests/envoy/provision_batch_test.go | 201 ++++++++++++++++++ tests/envoy/provision_test.go | 3 + tests/envoy/shaping_test.go | 8 +- .../provision_batch/app_1/1000_namespace.yaml | 3 + .../provision_batch/app_1/1100_modules.yaml | 43 ++++ .../provision_batch/app_1/1200_pages.yaml | 38 ++++ .../provision_batch/app_1/1300_charts.yaml | 8 + .../app_1/1400_record_settings.yaml | 5 + .../provision_batch/app_2/1000_namespace.yaml | 3 + .../provision_batch/app_2/1100_modules.yaml | 43 ++++ .../provision_batch/app_2/1200_pages.yaml | 38 ++++ .../provision_batch/app_2/1300_charts.yaml | 8 + .../app_2/1400_record_settings.yaml | 5 + 13 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 tests/envoy/provision_batch_test.go create mode 100644 tests/envoy/testdata/provision_batch/app_1/1000_namespace.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_1/1100_modules.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_1/1200_pages.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_1/1300_charts.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_1/1400_record_settings.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_2/1000_namespace.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_2/1100_modules.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_2/1200_pages.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_2/1300_charts.yaml create mode 100644 tests/envoy/testdata/provision_batch/app_2/1400_record_settings.yaml diff --git a/tests/envoy/provision_batch_test.go b/tests/envoy/provision_batch_test.go new file mode 100644 index 000000000..176930ef3 --- /dev/null +++ b/tests/envoy/provision_batch_test.go @@ -0,0 +1,201 @@ +package envoy + +import ( + "context" + "fmt" + "strconv" + "testing" + + "github.com/cortezaproject/corteza-server/compose/types" + su "github.com/cortezaproject/corteza-server/pkg/envoy/store" + "github.com/cortezaproject/corteza-server/store" + "github.com/stretchr/testify/require" +) + +// TestProvision_batch simulates the worst possible case, where two namespaces +// have exact same items. +func TestProvision_batch(t *testing.T) { + var ( + ctx = context.Background() + s, err = initStore(ctx) + ) + + if err != nil { + t.Fatalf("failed to init sqlite in-memory db: %v", err) + } + + ni := uint64(0) + su.NextID = func() uint64 { + ni++ + return ni + } + + prepare := func(ctx context.Context, s store.Storer, t *testing.T, suite string) (*require.Assertions, error) { + req := require.New(t) + + nn, err := dd(ctx, suite) + req.NoError(err) + + return req, encode(ctx, s, nn) + } + + // Prepare + s, err = initStore(ctx) + err = ce( + err, + + s.TruncateActionlogs(ctx), + s.TruncateApplications(ctx), + s.TruncateAttachments(ctx), + s.TruncateComposeAttachments(ctx), + s.TruncateComposeCharts(ctx), + s.TruncateComposeNamespaces(ctx), + s.TruncateComposeModules(ctx), + s.TruncateComposeModuleFields(ctx), + s.TruncateComposePages(ctx), + s.TruncateComposeRecords(ctx, nil), + + storeRole(ctx, s, 1, "everyone"), + storeRole(ctx, s, 2, "admins"), + ) + if err != nil { + t.Fatal(err.Error()) + } + + req, err := prepare(ctx, s, t, "provision_batch") + req.NoError(err) + + checkBatchProvision(ctx, t, req, s, "ns1") + checkBatchProvision(ctx, t, req, s, "ns2") +} + +func checkBatchProvision(ctx context.Context, t *testing.T, req *require.Assertions, s store.Storer, slug string) { + var ( + ns = &types.Namespace{} + mod1 = &types.Module{} + mod2 = &types.Module{} + mods = &types.Module{} + pg1 = &types.Page{} + rpg2 = &types.Page{} + chr1 = &types.Chart{} + rr = types.RecordSet{} + ) + + // Preload things + // * NS + ns, err := store.LookupComposeNamespaceBySlug(ctx, s, slug) + req.NoError(err) + req.NotNil(ns) + + // * Mods + mod1, err = fullModLoad(ctx, s, req, ns.ID, "mod1") + req.NoError(err) + req.NotNil(mod1) + + mod2, err = fullModLoad(ctx, s, req, ns.ID, "mod2") + req.NoError(err) + req.NotNil(mod2) + + mods, err = fullModLoad(ctx, s, req, ns.ID, "settings") + req.NoError(err) + req.NotNil(mods) + + // * Pages + pg1, err = store.LookupComposePageByNamespaceIDHandle(ctx, s, ns.ID, "pg1") + req.NoError(err) + req.NotNil(pg1) + + rpg2, err = store.LookupComposePageByNamespaceIDHandle(ctx, s, ns.ID, "rpg2") + req.NoError(err) + req.NotNil(rpg2) + + // * Charts + chr1, err = store.LookupComposeChartByNamespaceIDHandle(ctx, s, ns.ID, "chr1") + req.NoError(err) + req.NotNil(chr1) + + // * Records + rr, _, err = store.SearchComposeRecords(ctx, s, mods, types.RecordFilter{ + ModuleID: mods.ID, + NamespaceID: ns.ID, + }) + req.NoError(err) + req.NotNil(rr) + req.Len(rr, 1) + + // Check things + t.Run("NS", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s name", slug), ns.Name) + }) + + t.Run("mod1", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s mod1 name", slug), mod1.Name) + req.Len(mod1.Fields, 1) + + f1 := mod1.Fields[0] + req.Equal(strconv.FormatUint(mod2.ID, 10), f1.Options.String("moduleID")) + }) + + t.Run("mod2", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s mod2 name", slug), mod2.Name) + req.Len(mod2.Fields, 3) + + f1 := mod2.Fields[1] + req.Equal(strconv.FormatUint(mod2.ID, 10), f1.Options.String("moduleID")) + }) + + t.Run("mods", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s settings", slug), mods.Name) + req.Len(mods.Fields, 1) + }) + + t.Run("pg1", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s pg1 title", slug), pg1.Title) + req.Len(pg1.Blocks, 4) + + req.Equal("pg1 RecordList", pg1.Blocks[0].Title) + req.Equal(strconv.FormatUint(mod1.ID, 10), pg1.Blocks[0].Options["moduleID"]) + + req.Equal("pg1 Chart", pg1.Blocks[1].Title) + req.Equal(strconv.FormatUint(chr1.ID, 10), pg1.Blocks[1].Options["chartID"]) + + req.Equal("pg1 Calendar", pg1.Blocks[2].Title) + f := pg1.Blocks[2].Options["feeds"].([]interface{})[0] + feed, _ := f.(map[string]interface{}) + fOpts, _ := (feed["options"]).(map[string]interface{}) + id, _ := fOpts["moduleID"].(string) + req.Equal(strconv.FormatUint(mod1.ID, 10), id) + + req.Equal("pg1 Metric", pg1.Blocks[3].Title) + m := pg1.Blocks[3].Options["metrics"].([]interface{})[0] + mops, _ := m.(map[string]interface{}) + id = mops["moduleID"].(string) + req.Equal(strconv.FormatUint(mod1.ID, 10), id) + }) + + t.Run("rpg2", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s Record page for module \"mod1\"", slug), rpg2.Title) + }) + + t.Run("chr1", func(t *testing.T) { + req.Equal(fmt.Sprintf("%s chr1 name", slug), chr1.Name) + req.Equal(mod1.ID, chr1.Config.Reports[0].ModuleID) + }) + + t.Run("rr", func(t *testing.T) { + req.Len(rr, 1) + v := rr[0].Values.FilterByName("s1")[0] + req.Equal(fmt.Sprintf("%s value", slug), v.Value) + }) +} + +func fullModLoad(ctx context.Context, s store.Storer, req *require.Assertions, nsID uint64, handle string) (*types.Module, error) { + mod, err := store.LookupComposeModuleByNamespaceIDHandle(ctx, s, nsID, handle) + req.NoError(err) + req.NotNil(mod) + + mod.Fields, _, err = store.SearchComposeModuleFields(ctx, s, types.ModuleFieldFilter{ModuleID: []uint64{mod.ID}}) + req.NoError(err) + req.NotNil(mod.Fields) + return mod, err +} diff --git a/tests/envoy/provision_test.go b/tests/envoy/provision_test.go index e99f89c74..7a8fb697b 100644 --- a/tests/envoy/provision_test.go +++ b/tests/envoy/provision_test.go @@ -67,6 +67,8 @@ func TestProvision(t *testing.T) { err = ce( err, + s.TruncateRbacRules(ctx), + s.TruncateRoles(ctx), s.TruncateActionlogs(ctx), s.TruncateApplications(ctx), s.TruncateAttachments(ctx), @@ -76,6 +78,7 @@ func TestProvision(t *testing.T) { s.TruncateComposeModules(ctx), s.TruncateComposeModuleFields(ctx), s.TruncateComposePages(ctx), + s.TruncateComposeRecords(ctx, nil), storeRole(ctx, s, 1, "everyone"), storeRole(ctx, s, 2, "admins"), diff --git a/tests/envoy/shaping_test.go b/tests/envoy/shaping_test.go index f292187a6..6a05ec7a4 100644 --- a/tests/envoy/shaping_test.go +++ b/tests/envoy/shaping_test.go @@ -57,11 +57,17 @@ func TestShaping_simple(t *testing.T) { err = ce( err, - s.TruncateRoleMembers(ctx), + s.TruncateRbacRules(ctx), s.TruncateRoles(ctx), + s.TruncateActionlogs(ctx), + s.TruncateApplications(ctx), + s.TruncateAttachments(ctx), + s.TruncateComposeAttachments(ctx), + s.TruncateComposeCharts(ctx), s.TruncateComposeNamespaces(ctx), s.TruncateComposeModules(ctx), s.TruncateComposeModuleFields(ctx), + s.TruncateComposePages(ctx), storeRole(ctx, s, 1, "everyone"), storeRole(ctx, s, 2, "admins"), diff --git a/tests/envoy/testdata/provision_batch/app_1/1000_namespace.yaml b/tests/envoy/testdata/provision_batch/app_1/1000_namespace.yaml new file mode 100644 index 000000000..137005b54 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_1/1000_namespace.yaml @@ -0,0 +1,3 @@ +namespaces: + ns1: + name: ns1 name diff --git a/tests/envoy/testdata/provision_batch/app_1/1100_modules.yaml b/tests/envoy/testdata/provision_batch/app_1/1100_modules.yaml new file mode 100644 index 000000000..92468095e --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_1/1100_modules.yaml @@ -0,0 +1,43 @@ +# Provides a complete set of things to cover regarding modules and module fields. +# mod1: relates to mod2 +# mod2: defines a self-ref +# settings: regular module + +namespace: ns1 +modules: + mod1: + name: ns1 mod1 name + fields: + f1: + label: f1 label + kind: Record + options: + labelField: f_label + module: mod2 + queryFields: + - f1 + + mod2: + name: ns1 mod2 name + fields: + f_label: + label: f_label record label + f_ref_self: + label: f_ref_self label + kind: Record + options: + labelField: f_label + module: mod2 + queryFields: + - f1 + f1: + label: f1 label + kind: String + required: true + + settings: + name: ns1 settings + fields: + s1: + label: s1 label + kind: String diff --git a/tests/envoy/testdata/provision_batch/app_1/1200_pages.yaml b/tests/envoy/testdata/provision_batch/app_1/1200_pages.yaml new file mode 100644 index 000000000..887c531f4 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_1/1200_pages.yaml @@ -0,0 +1,38 @@ +namespace: ns1 +pages: + pg1: + title: ns1 pg1 title + blocks: + - title: pg1 RecordList + kind: RecordList + xywh: [0, 1, 1, 1] + options: + module: mod1 + + - title: pg1 Chart + kind: Chart + xywh: [0, 2, 1, 1] + options: + chart: chr1 + + - title: pg1 Calendar + kind: Calendar + xywh: [0, 2, 1, 1] + options: + feeds: + - endField: f1 + options: + module: mod1 + + - title: pg1 Metric + kind: Metric + options: + metrics: + - module: mod1 + + + children: + rpg2: + handle: rpg2 + module: mod1 + title: ns1 Record page for module "mod1" diff --git a/tests/envoy/testdata/provision_batch/app_1/1300_charts.yaml b/tests/envoy/testdata/provision_batch/app_1/1300_charts.yaml new file mode 100644 index 000000000..7a5ab47c0 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_1/1300_charts.yaml @@ -0,0 +1,8 @@ +namespace: ns1 +charts: + chr1: + name: ns1 chr1 name + config: + reports: + - dimensions: + module: mod1 diff --git a/tests/envoy/testdata/provision_batch/app_1/1400_record_settings.yaml b/tests/envoy/testdata/provision_batch/app_1/1400_record_settings.yaml new file mode 100644 index 000000000..b725062ae --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_1/1400_record_settings.yaml @@ -0,0 +1,5 @@ +namespace: ns1 +records: + settings: + - values: + s1: ns1 value diff --git a/tests/envoy/testdata/provision_batch/app_2/1000_namespace.yaml b/tests/envoy/testdata/provision_batch/app_2/1000_namespace.yaml new file mode 100644 index 000000000..7da45d4e8 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_2/1000_namespace.yaml @@ -0,0 +1,3 @@ +namespaces: + ns2: + name: ns2 name diff --git a/tests/envoy/testdata/provision_batch/app_2/1100_modules.yaml b/tests/envoy/testdata/provision_batch/app_2/1100_modules.yaml new file mode 100644 index 000000000..1e85aa193 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_2/1100_modules.yaml @@ -0,0 +1,43 @@ +# Provides a complete set of things to cover regarding modules and module fields. +# mod1: relates to mod2 +# mod2: defines a self-ref +# settings: regular module + +namespace: ns2 +modules: + mod1: + name: ns2 mod1 name + fields: + f1: + label: f1 label + kind: Record + options: + labelField: f_label + module: mod2 + queryFields: + - f1 + + mod2: + name: ns2 mod2 name + fields: + f_label: + label: f_label record label + f_ref_self: + label: f_ref_self label + kind: Record + options: + labelField: f_label + module: mod2 + queryFields: + - f1 + f1: + label: f1 label + kind: String + required: true + + settings: + name: ns2 settings + fields: + s1: + label: s1 label + kind: String diff --git a/tests/envoy/testdata/provision_batch/app_2/1200_pages.yaml b/tests/envoy/testdata/provision_batch/app_2/1200_pages.yaml new file mode 100644 index 000000000..8a4c8c8cf --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_2/1200_pages.yaml @@ -0,0 +1,38 @@ +namespace: ns2 +pages: + pg1: + title: ns2 pg1 title + blocks: + - title: pg1 RecordList + kind: RecordList + xywh: [0, 1, 1, 1] + options: + module: mod1 + + - title: pg1 Chart + kind: Chart + xywh: [0, 2, 1, 1] + options: + chart: chr1 + + - title: pg1 Calendar + kind: Calendar + xywh: [0, 2, 1, 1] + options: + feeds: + - endField: f1 + options: + module: mod1 + + - title: pg1 Metric + kind: Metric + options: + metrics: + - module: mod1 + + + children: + rpg2: + handle: rpg2 + module: mod1 + title: ns2 Record page for module "mod1" diff --git a/tests/envoy/testdata/provision_batch/app_2/1300_charts.yaml b/tests/envoy/testdata/provision_batch/app_2/1300_charts.yaml new file mode 100644 index 000000000..8f2417599 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_2/1300_charts.yaml @@ -0,0 +1,8 @@ +namespace: ns2 +charts: + chr1: + name: ns2 chr1 name + config: + reports: + - dimensions: + module: mod1 diff --git a/tests/envoy/testdata/provision_batch/app_2/1400_record_settings.yaml b/tests/envoy/testdata/provision_batch/app_2/1400_record_settings.yaml new file mode 100644 index 000000000..ee7740948 --- /dev/null +++ b/tests/envoy/testdata/provision_batch/app_2/1400_record_settings.yaml @@ -0,0 +1,5 @@ +namespace: ns2 +records: + settings: + - values: + s1: ns2 value