From 78fc9f54c1112ffc792aa11c8495648625fa639f Mon Sep 17 00:00:00 2001 From: Jure Skelin Date: Tue, 17 Dec 2024 16:43:38 +0100 Subject: [PATCH] test(segment): add additional test cases --- cmd/monaco/download/download_configs_test.go | 86 +++++++++++-------- pkg/download/segment/download_test.go | 87 +++++++++++++++++++- 2 files changed, 137 insertions(+), 36 deletions(-) diff --git a/cmd/monaco/download/download_configs_test.go b/cmd/monaco/download/download_configs_test.go index 0c21bd9e8..7d24750e6 100644 --- a/cmd/monaco/download/download_configs_test.go +++ b/cmd/monaco/download/download_configs_test.go @@ -20,6 +20,7 @@ package download import ( "errors" + "strconv" "testing" "github.com/spf13/afero" @@ -185,18 +186,19 @@ func TestDownload_Options(t *testing.T) { config, settings, bucket, automation, document, openpipeline, segment bool } tests := []struct { - name string - given downloadConfigsOptions - want wantDownload + name string + given downloadConfigsOptions + want wantDownload + featureFlags map[featureflags.TemporaryFlag]bool }{ { - "download all if options are not limiting", - downloadConfigsOptions{ + name: "download all if options are not limiting", + given: downloadConfigsOptions{ downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}, OAuth: &manifest.OAuth{}}, // OAuth and Token required to download whole config }, }, - wantDownload{ + want: wantDownload{ config: true, settings: true, bucket: true, @@ -207,93 +209,107 @@ func TestDownload_Options(t *testing.T) { }, }, { - "only settings requested", - downloadConfigsOptions{ + name: "only settings requested", + given: downloadConfigsOptions{ onlySettings: true, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}}, }}, - wantDownload{settings: true}, + want: wantDownload{settings: true}, }, { - "specific settings requested", - downloadConfigsOptions{ + name: "specific settings requested", + given: downloadConfigsOptions{ specificSchemas: []string{"some:schema"}, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}}, }}, - wantDownload{settings: true}, + want: wantDownload{settings: true}, }, { - "only documents requested", - downloadConfigsOptions{ + name: "only documents requested", + given: downloadConfigsOptions{ onlyDocuments: true, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{OAuth: &manifest.OAuth{}}, }}, - wantDownload{document: true}, + want: wantDownload{document: true}, }, { - "only openpipeline requested", - downloadConfigsOptions{ + name: "only openpipeline requested", + given: downloadConfigsOptions{ onlyOpenPipeline: true, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{OAuth: &manifest.OAuth{}}, }}, - wantDownload{openpipeline: true}, + want: wantDownload{openpipeline: true}, }, { - "only segment requested", - downloadConfigsOptions{ + name: "only segment requested with FF on", + given: downloadConfigsOptions{ onlySegment: true, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{OAuth: &manifest.OAuth{}}, }}, - wantDownload{segment: true}, + featureFlags: map[featureflags.TemporaryFlag]bool{featureflags.Segments: true}, + want: wantDownload{segment: true}, }, { - "only apis requested", - downloadConfigsOptions{ + name: "only segment requested with FF off", + given: downloadConfigsOptions{ + onlySegment: true, + downloadOptionsShared: downloadOptionsShared{ + auth: manifest.Auth{OAuth: &manifest.OAuth{}}, + }}, + featureFlags: map[featureflags.TemporaryFlag]bool{featureflags.Segments: false}, + want: wantDownload{}, + }, + { + name: "only apis requested", + given: downloadConfigsOptions{ onlyAPIs: true, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}}, }}, - wantDownload{config: true}, + want: wantDownload{config: true}, }, { - "specific config apis requested", - downloadConfigsOptions{ + name: "specific config apis requested", + given: downloadConfigsOptions{ specificAPIs: []string{"alerting-profile"}, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}}, }}, - wantDownload{config: true}, + want: wantDownload{config: true}, }, { - "only automations requested", - downloadConfigsOptions{ + name: "only automations requested", + given: downloadConfigsOptions{ downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{OAuth: &manifest.OAuth{}}, }, onlyAutomation: true, }, - wantDownload{automation: true}, + want: wantDownload{automation: true}, }, { - "specific APIs and schemas", - downloadConfigsOptions{ + name: "specific APIs and schemas", + given: downloadConfigsOptions{ specificAPIs: []string{"alerting-profile"}, specificSchemas: []string{"some:schema"}, downloadOptionsShared: downloadOptionsShared{ auth: manifest.Auth{Token: &manifest.AuthSecret{}}, }}, - wantDownload{config: true, settings: true}, + want: wantDownload{config: true, settings: true}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Setenv(featureflags.Temporary[featureflags.Segments].EnvName(), "true") + for ff, v := range tt.featureFlags { + t.Setenv(string(ff), strconv.FormatBool(v)) + } + fn := downloadFn{ classicDownload: func(client.ConfigClient, string, api.APIs, classic.ContentFilters) (projectv2.ConfigsPerType, error) { if !tt.want.config { @@ -331,7 +347,7 @@ func TestDownload_Options(t *testing.T) { } return nil, nil }, - segmentDownload: func(b segment.Client, s string) (projectv2.ConfigsPerType, error) { + segmentDownload: func(b segment.DownloadSegmentClient, s string) (projectv2.ConfigsPerType, error) { if !tt.want.segment { t.Fatalf("segment download was not meant to be called but was") } diff --git a/pkg/download/segment/download_test.go b/pkg/download/segment/download_test.go index cea51a056..5c5ba8859 100644 --- a/pkg/download/segment/download_test.go +++ b/pkg/download/segment/download_test.go @@ -69,7 +69,7 @@ func TestDownloader_Download(t *testing.T) { assert.Equal(t, "uid", actual.OriginObjectId) actualTemplate, err := actual.Template.Content() assert.NoError(t, err) - assert.JSONEq(t, `{"name":"segment_name"}`, actualTemplate) + assert.JSONEq(t, `{"name":"segment_name"}`, actualTemplate, "uid, externalId and version must be deleted") assert.False(t, actual.Skip) assert.Empty(t, actual.Group) @@ -100,6 +100,23 @@ func TestDownloader_Download(t *testing.T) { assert.Empty(t, result[string(config.SegmentID)]) }) + t.Run("Downloading multiple segments works", func(t *testing.T) { + c := stubClient{getAll: func() ([]coreLib.Response, error) { + return []coreLib.Response{ + {Data: []byte(`{"uid": "uid1","externalId": "some_external_ID","version": 1,"name": "segment_name"}`), StatusCode: http.StatusOK}, + {Data: []byte(`{"uid": "uid2","externalId": "some_external_ID","version": 1,"name": "segment_name"}`), StatusCode: http.StatusOK}, + {Data: []byte(`{"uid": "uid3","externalId": "some_external_ID","version": 1,"name": "segment_name"}`), StatusCode: http.StatusOK}, + }, nil + }} + + actual, err := segment.Download(c, "project") + + assert.NoError(t, err) + assert.Len(t, actual, 1) + + assert.Len(t, actual[string(config.SegmentID)], 3, "must contain all downloaded configs") + }) + t.Run("no error downloading segments with faulty client", func(t *testing.T) { c := stubClient{getAll: func() ([]coreLib.Response, error) { return []coreLib.Response{}, errors.New("some unexpected error") @@ -109,4 +126,72 @@ func TestDownloader_Download(t *testing.T) { assert.NoError(t, err) assert.Empty(t, result) }) + + t.Run("complete real payload", func(t *testing.T) { + given := `{ + "uid": "PfdP4Qp1IJG", + "externalId": "some_external_ID", + "name": "Host based logs", + "variables": { + "type": "query", + "value": "fetch dt.entity.host | fields id, entity.name" + }, + "isPublic": true, + "owner": "cd3fc936-5b1a-4d6c-b1b6-f1025dbde7d5", + "allowedOperations": [ + "READ" + ], + "includes": [ + { + "filter": "{\"type\":\"Group\",\"range\":{\"from\":0,\"to\":58},\"logicalOperator\":\"OR\",\"explicit\":false,\"children\":[{\"type\":\"Statement\",\"range\":{\"from\":0,\"to\":22},\"key\":{\"type\":\"Key\",\"textValue\":\"dt.entity.host\",\"value\":\"dt.entity.host\",\"range\":{\"from\":0,\"to\":14}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":15,\"to\":16}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$id\\\"\",\"value\":\"$id\",\"range\":{\"from\":17,\"to\":22},\"isEscaped\":true}},{\"type\":\"LogicalOperator\",\"textValue\":\"OR\",\"value\":\"OR\",\"range\":{\"from\":23,\"to\":25}},{\"type\":\"Statement\",\"range\":{\"from\":26,\"to\":57},\"key\":{\"type\":\"Key\",\"textValue\":\"dt.entity.host\",\"value\":\"dt.entity.host\",\"range\":{\"from\":26,\"to\":40}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":41,\"to\":42}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$entity.name\\\"\",\"value\":\"$entity.name\",\"range\":{\"from\":43,\"to\":57},\"isEscaped\":true}}]}", + "dataObject": "logs", + "applyTo": [] + }, + { + "filter": "{\"type\":\"Group\",\"range\":{\"from\":0,\"to\":11},\"logicalOperator\":\"AND\",\"explicit\":false,\"children\":[{\"type\":\"Statement\",\"range\":{\"from\":0,\"to\":10},\"key\":{\"type\":\"Key\",\"textValue\":\"id\",\"value\":\"id\",\"range\":{\"from\":0,\"to\":2}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":3,\"to\":4}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$id\\\"\",\"value\":\"$id\",\"range\":{\"from\":5,\"to\":10},\"isEscaped\":true}}]}", + "dataObject": "dt.entity.host", + "applyTo": [] + } + ], + "version": 16 +}` + expected := `{ + "name": "Host based logs", + "variables": { + "type": "query", + "value": "fetch dt.entity.host | fields id, entity.name" + }, + "isPublic": true, + "owner": "cd3fc936-5b1a-4d6c-b1b6-f1025dbde7d5", + "allowedOperations": [ + "READ" + ], + "includes": [ + { + "filter": "{\"type\":\"Group\",\"range\":{\"from\":0,\"to\":58},\"logicalOperator\":\"OR\",\"explicit\":false,\"children\":[{\"type\":\"Statement\",\"range\":{\"from\":0,\"to\":22},\"key\":{\"type\":\"Key\",\"textValue\":\"dt.entity.host\",\"value\":\"dt.entity.host\",\"range\":{\"from\":0,\"to\":14}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":15,\"to\":16}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$id\\\"\",\"value\":\"$id\",\"range\":{\"from\":17,\"to\":22},\"isEscaped\":true}},{\"type\":\"LogicalOperator\",\"textValue\":\"OR\",\"value\":\"OR\",\"range\":{\"from\":23,\"to\":25}},{\"type\":\"Statement\",\"range\":{\"from\":26,\"to\":57},\"key\":{\"type\":\"Key\",\"textValue\":\"dt.entity.host\",\"value\":\"dt.entity.host\",\"range\":{\"from\":26,\"to\":40}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":41,\"to\":42}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$entity.name\\\"\",\"value\":\"$entity.name\",\"range\":{\"from\":43,\"to\":57},\"isEscaped\":true}}]}", + "dataObject": "logs", + "applyTo": [] + }, + { + "filter": "{\"type\":\"Group\",\"range\":{\"from\":0,\"to\":11},\"logicalOperator\":\"AND\",\"explicit\":false,\"children\":[{\"type\":\"Statement\",\"range\":{\"from\":0,\"to\":10},\"key\":{\"type\":\"Key\",\"textValue\":\"id\",\"value\":\"id\",\"range\":{\"from\":0,\"to\":2}},\"operator\":{\"type\":\"ComparisonOperator\",\"textValue\":\"=\",\"value\":\"=\",\"range\":{\"from\":3,\"to\":4}},\"value\":{\"type\":\"String\",\"textValue\":\"\\\"$id\\\"\",\"value\":\"$id\",\"range\":{\"from\":5,\"to\":10},\"isEscaped\":true}}]}", + "dataObject": "dt.entity.host", + "applyTo": [] + } + ] +}` + + c := stubClient{getAll: func() ([]coreLib.Response, error) { + return []coreLib.Response{{StatusCode: http.StatusOK, Data: []byte(given)}}, nil + }} + + result, err := segment.Download(c, "project") + assert.NoError(t, err) + + actual := result[string(config.SegmentID)][0].Template + assert.Equal(t, "PfdP4Qp1IJG", actual.ID()) + + actualContent, err := actual.Content() + assert.NoError(t, err) + assert.JSONEq(t, expected, actualContent) + }) }