This is an automated email from the ASF dual-hosted git repository.
ka94 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 0e93aa117 test: Support manual e2e testing (#5085)
0e93aa117 is described below
commit 0e93aa1175b236feebd3728edd18012546241746
Author: Keon Amini <[email protected]>
AuthorDate: Mon Jun 12 14:28:28 2023 -0500
test: Support manual e2e testing (#5085)
---
backend/Makefile | 2 +-
backend/test/e2e/manual/.gitignore | 1 +
backend/test/e2e/manual/Readme.md | 44 ++++++
backend/test/e2e/manual/azuredevops/azure_test.go | 146 ++++++++++++++++++
backend/test/e2e/manual/azuredevops/models.go | 67 +++++++++
backend/test/e2e/manual/gitlab/gitlab_test.go | 155 +++++++++++++++++++
backend/test/e2e/manual/gitlab/models.go | 23 +++
backend/test/e2e/manual/pagerduty/models.go | 26 ++++
.../test/e2e/manual/pagerduty/pagerduty_test.go | 164 +++++++++++++++++++++
backend/test/e2e/remote/helper.go | 2 +-
backend/test/helper/api.go | 2 +-
backend/test/helper/client.go | 14 +-
backend/test/helper/models.go | 10 ++
backend/test/helper/utils.go | 10 ++
14 files changed, 656 insertions(+), 10 deletions(-)
diff --git a/backend/Makefile b/backend/Makefile
index 0dec2a7ee..01d1f343d 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -115,7 +115,7 @@ e2e-test:
set -e;\
go run ./test/init.go || exit $$?;\
exit_code=0;\
- for m in $$(go list ./test/e2e/...); do \
+ for m in $$(go list ./test/e2e/... | grep -v manual/); do \
echo $$m; go test -p 1 -timeout 300s -v $$m || exit_code=$$?; \
done; \
exit $$exit_code
diff --git a/backend/test/e2e/manual/.gitignore
b/backend/test/e2e/manual/.gitignore
new file mode 100644
index 000000000..606921f2f
--- /dev/null
+++ b/backend/test/e2e/manual/.gitignore
@@ -0,0 +1 @@
+*_local_test.go
\ No newline at end of file
diff --git a/backend/test/e2e/manual/Readme.md
b/backend/test/e2e/manual/Readme.md
new file mode 100644
index 000000000..715fbc468
--- /dev/null
+++ b/backend/test/e2e/manual/Readme.md
@@ -0,0 +1,44 @@
+Tests in this directory are not meant to be run by CICD automation, but rather
manually by developers on their machines.
+They serve as workflow tests and mimic the sequence of actions that would be
performed via the UI. These
+tests will typically connect to real data-sources, so any data-source specific
data/credential needs to be supplied
+externally. The convention we are using is to wrap all such variables in a
Config struct, placed in a `models.go` file,
+which is loaded in at runtime. Populating these structs and making them
available to the tests will be your responsibility.
+See the example below.
+
+You can also add your own manual tests by having the test files follow the
pattern *_local_test.go to exclude them
+from git's tracking.
+
+Example:
+
+In `models.go` define
+```go
+package azuredevops
+
+ type TestConfig struct {
+ Org string
+ Project string
+ Token string
+ }
+```
+
+and load it into your test function (if you write one) via
+```go
+ cfg := helper.GetTestConfig[TestConfig]()
+```
+
+In `azure_local_test.go` (or any git-ignorable file) you write your setup.
+```go
+package azuredevops
+
+import "github.com/apache/incubator-devlake/test/helper"
+
+func init() {
+ helper.SetTestConfig(TestConfig{
+ Org: "???",
+ Project: "???",
+ Token: "??????",
+ })
+}
+
+// Your custom test cases (optional)
+```
\ No newline at end of file
diff --git a/backend/test/e2e/manual/azuredevops/azure_test.go
b/backend/test/e2e/manual/azuredevops/azure_test.go
new file mode 100644
index 000000000..613a97e04
--- /dev/null
+++ b/backend/test/e2e/manual/azuredevops/azure_test.go
@@ -0,0 +1,146 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package azuredevops
+
+import (
+ "fmt"
+ "github.com/apache/incubator-devlake/core/config"
+ "github.com/apache/incubator-devlake/core/models"
+ "github.com/apache/incubator-devlake/core/models/common"
+ "github.com/apache/incubator-devlake/core/plugin"
+ gitextractor
"github.com/apache/incubator-devlake/plugins/gitextractor/impl"
+ "github.com/apache/incubator-devlake/test/helper"
+ "github.com/stretchr/testify/require"
+ "testing"
+ "time"
+)
+
+const (
+ azurePlugin = "azuredevops"
+)
+
+func TestAzure(t *testing.T) {
+ cfg := helper.GetTestConfig[TestConfig]()
+ client := helper.ConnectLocalServer(t, &helper.LocalClientConfig{
+ ServerPort: 8089,
+ DbURL: config.GetConfig().GetString("E2E_DB_URL"),
+ CreateServer: true,
+ DropDb: false,
+ TruncateDb: true,
+ Plugins: map[string]plugin.PluginMeta{
+ "gitextractor": gitextractor.GitExtractor{},
+ },
+ })
+ client.SetTimeout(60 * time.Second)
+ // Wait for plugin registration
+ time.Sleep(5 * time.Second)
+ fmt.Println("Create new connection")
+ connection := client.CreateConnection(azurePlugin,
+ AzureConnection{
+ Name: "azure_conn",
+ Token: cfg.Token,
+ Organization: cfg.Org,
+ },
+ )
+ client.SetTimeout(0)
+ client.SetPipelineTimeout(0)
+ conns := client.ListConnections(azurePlugin)
+ require.Greater(t, len(conns), 0)
+ t.Run("v200-plugin", func(t *testing.T) {
+ outputProject := client.CreateProject(&helper.ProjectConfig{
+ ProjectName: "project-1",
+ EnableDora: true,
+ })
+ projects := client.ListProjects()
+ require.Equal(t, 1, len(projects.Projects))
+ project := projects.Projects[0]
+ repoConfig :=
helper.Cast[AzureGitRepositoryConfig](client.CreateScopeConfig(azurePlugin,
connection.ID,
+ AzureGitRepositoryConfig{
+ ScopeConfig: common.ScopeConfig{
+ Entities: []string{
+ plugin.DOMAIN_TYPE_CICD,
+ plugin.DOMAIN_TYPE_CODE,
+ plugin.DOMAIN_TYPE_CODE_REVIEW,
+ },
+ },
+ Refdiff: Refdiff{
+ TagsPattern: ".*",
+ TagsLimit: 1,
+ TagsOrder: "",
+ },
+ DeploymentPattern: ".*",
+ ProductionPattern: ".*",
+ },
+ ))
+ _ = repoConfig
+ remoteScopes := client.RemoteScopes(helper.RemoteScopesQuery{
+ PluginName: azurePlugin,
+ ConnectionId: connection.ID,
+ GroupId: fmt.Sprintf("%s/%s", cfg.Org,
cfg.Project),
+ PageToken: "",
+ Params: nil,
+ })
+ scopes :=
helper.Cast[[]AzureGitRepo](client.CreateScopes(azurePlugin, connection.ID,
remoteScopesToScopes(remoteScopes, cfg.Repos)...))
+ scopesCount := len(scopes)
+ scopesResponse := client.ListScopes(azurePlugin, connection.ID,
false)
+ require.Equal(t, scopesCount, len(scopesResponse))
+ // associate scopes with the scope config
+ for _, scope := range scopes {
+ scope.ScopeConfigId = repoConfig.ID
+ scope =
helper.Cast[AzureGitRepo](client.UpdateScope(azurePlugin, connection.ID,
scope.Id, scope))
+ require.Equal(t, repoConfig.ID, scope.ScopeConfigId)
+ }
+ // create bp_scopes from the scopes
+ var bpScopes []*plugin.BlueprintScopeV200
+ for _, scope := range scopes {
+ bpScopes = append(bpScopes, &plugin.BlueprintScopeV200{
+ Id: scope.Id,
+ Name: scope.Name,
+ })
+ }
+ // create the bp
+ bp := client.CreateBasicBlueprintV2(connection.Name,
&helper.BlueprintV2Config{
+ Connection: &plugin.BlueprintConnectionV200{
+ Plugin: azurePlugin,
+ ConnectionId: connection.ID,
+ Scopes: bpScopes,
+ },
+ TimeAfter: nil,
+ SkipOnFail: false,
+ ProjectName: project.Name,
+ })
+ // get the project ... should have a reference to the blueprint
now
+ outputProject = client.GetProject(project.Name)
+ require.Equal(t, bp.Name, outputProject.Blueprint.Name)
+ // run the bp
+ pipeline := client.TriggerBlueprint(bp.ID)
+ require.Equal(t, models.TASK_COMPLETED, pipeline.Status)
+ })
+ fmt.Println("========DONE=======")
+}
+
+func remoteScopesToScopes(remoteScopes helper.RemoteScopesOutput, filters
[]string) []any {
+ var a []any
+ for _, c := range remoteScopes.Children {
+ repo := helper.Cast[AzureGitRepo](c.Data)
+ if len(filters) == 0 || helper.Contains(filters, repo.Name) {
+ a = append(a, repo)
+ }
+ }
+ return a
+}
diff --git a/backend/test/e2e/manual/azuredevops/models.go
b/backend/test/e2e/manual/azuredevops/models.go
new file mode 100644
index 000000000..d40172fdd
--- /dev/null
+++ b/backend/test/e2e/manual/azuredevops/models.go
@@ -0,0 +1,67 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package azuredevops
+
+import (
+ "github.com/apache/incubator-devlake/core/models/common"
+)
+
+// These models correspond to Python models
+
+type (
+ Refdiff struct {
+ TagsPattern string
+ TagsLimit int
+ TagsOrder string
+ }
+
+ AzureConnection struct {
+ Name string
+ Token string
+ Organization string
+ }
+
+ AzureGitRepositoryConfig struct {
+ common.ScopeConfig
+ Refdiff Refdiff
+ DeploymentPattern string
+ ProductionPattern string
+ }
+
+ AzureGitRepo struct {
+ Id string
+ Name string
+ ConnectionId uint64
+ Url string
+ RemoteUrl string
+ DefaultBranch string
+ ProjectId string
+ OrgId string
+ ParentRepositoryUrl string
+ Provider string
+ // special field
+ ScopeConfigId uint64
+ }
+)
+
+type TestConfig struct {
+ Org string
+ Project string
+ Repos []string
+ Token string
+}
diff --git a/backend/test/e2e/manual/gitlab/gitlab_test.go
b/backend/test/e2e/manual/gitlab/gitlab_test.go
new file mode 100644
index 000000000..c4b0d8ad7
--- /dev/null
+++ b/backend/test/e2e/manual/gitlab/gitlab_test.go
@@ -0,0 +1,155 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package gitlab
+
+import (
+ "fmt"
+ "github.com/apache/incubator-devlake/core/config"
+ "github.com/apache/incubator-devlake/core/models"
+ "github.com/apache/incubator-devlake/core/models/common"
+ "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ gitextractor
"github.com/apache/incubator-devlake/plugins/gitextractor/impl"
+ gitlab "github.com/apache/incubator-devlake/plugins/gitlab/impl"
+ pluginmodels "github.com/apache/incubator-devlake/plugins/gitlab/models"
+ "github.com/apache/incubator-devlake/test/helper"
+ "github.com/stretchr/testify/require"
+ "testing"
+)
+
+const pluginName = "gitlab"
+
+func TestGitlabPlugin(t *testing.T) {
+ createConnection := func(cfg TestConfig, client *helper.DevlakeClient)
*helper.Connection {
+ conn := pluginmodels.GitlabConnection{
+ BaseConnection: api.BaseConnection{
+ Name: "gitlab-conn",
+ },
+ GitlabConn: pluginmodels.GitlabConn{
+ RestConnection: api.RestConnection{
+ Endpoint:
"https://gitlab.com/api/v4",
+ Proxy: "",
+ RateLimitPerHour: 0,
+ },
+ AccessToken: api.AccessToken{Token: cfg.Token},
+ },
+ }
+ client.TestConnection(pluginName, conn)
+ return client.CreateConnection(pluginName, conn)
+ }
+ client := helper.ConnectLocalServer(t, &helper.LocalClientConfig{
+ ServerPort: 8089,
+ DbURL: config.GetConfig().GetString("E2E_DB_URL"),
+ CreateServer: true,
+ DropDb: false,
+ TruncateDb: true,
+ Plugins: map[string]plugin.PluginMeta{
+ "gitlab": gitlab.Gitlab(""),
+ "gitextractor": gitextractor.GitExtractor{},
+ },
+ })
+ cfg := helper.GetTestConfig[TestConfig]()
+ connection := createConnection(cfg, client)
+ t.Run("blueprint v200", func(t *testing.T) {
+ rule :=
helper.Cast[pluginmodels.GitlabScopeConfig](client.CreateScopeConfig("gitlab",
connection.ID,
+ pluginmodels.GitlabScopeConfig{
+ ScopeConfig: common.ScopeConfig{
+ Entities: []string{
+ plugin.DOMAIN_TYPE_CICD,
+ plugin.DOMAIN_TYPE_CODE,
+ plugin.DOMAIN_TYPE_CODE_REVIEW,
+ },
+ },
+ Name: "rule-1",
+ PrType: "",
+ PrComponent: "",
+ PrBodyClosePattern: "",
+ IssueSeverity: "",
+ IssuePriority: "",
+ IssueComponent: "",
+ IssueTypeBug: "",
+ IssueTypeIncident: "",
+ IssueTypeRequirement: "",
+ DeploymentPattern: ".*",
+ ProductionPattern: ".*", // this
triggers dora
+ Refdiff: map[string]any{}, // this
is technically a true/false (nil or not)
+ }))
+ _ = rule
+ remoteScopes := client.RemoteScopes(helper.RemoteScopesQuery{
+ PluginName: pluginName,
+ ConnectionId: connection.ID,
+ PageToken: "",
+ Params: nil,
+ })
+ {
+ // this doesn't have any direct use-case (for testing
anyway)
+ searchRemoteScopes :=
client.SearchRemoteScopes(helper.SearchRemoteScopesQuery{
+ PluginName: pluginName,
+ ConnectionId: connection.ID,
+ Search: "projects",
+ Page: 10,
+ PageSize: 5,
+ Params: nil,
+ })
+ _ = searchRemoteScopes
+ }
+ var scopeData []any
+ for _, remoteScope := range remoteScopes.Children {
+ if remoteScope.Type == "scope" {
+ data :=
helper.Cast[pluginmodels.GitlabProject](remoteScope.Data)
+ if len(cfg.Projects) == 0 ||
helper.Contains(cfg.Projects, data.Name) {
+ data.ScopeConfigId = rule.ID
+ scopeData = append(scopeData, data)
+ }
+ }
+ }
+ createdScopes :=
helper.Cast[[]*pluginmodels.GitlabProject](client.CreateScopes(pluginName,
connection.ID, scopeData...))
+ listedScopes := client.ListScopes(pluginName, connection.ID,
false)
+ require.Equal(t, len(createdScopes), len(listedScopes))
+ outputProject := client.CreateProject(&helper.ProjectConfig{
+ ProjectName: fmt.Sprintf("project-%s", pluginName),
+ EnableDora: true,
+ })
+ projects := client.ListProjects()
+ require.Equal(t, 1, len(projects.Projects))
+ var scopes []*plugin.BlueprintScopeV200
+ for _, scope := range listedScopes {
+ project :=
helper.Cast[pluginmodels.GitlabProject](scope.Scope)
+ scopes = append(scopes, &plugin.BlueprintScopeV200{
+ Id: fmt.Sprintf("%s", project.ScopeId()),
+ Name: "blueprint-v200",
+ })
+ }
+ bp := client.CreateBasicBlueprintV2(connection.Name,
&helper.BlueprintV2Config{
+ Connection: &plugin.BlueprintConnectionV200{
+ Plugin: pluginName,
+ ConnectionId: connection.ID,
+ Scopes: scopes,
+ },
+ SkipOnFail: true,
+ ProjectName: outputProject.Name,
+ })
+ // get the project ... should have a reference to the blueprint
now
+ outputProject = client.GetProject(outputProject.Name)
+ require.Equal(t, bp.Name, outputProject.Blueprint.Name)
+ fmt.Printf("=========================Triggering blueprint for
project %s =========================\n", outputProject.Name)
+ pipeline := client.TriggerBlueprint(bp.ID)
+ require.Equal(t, models.TASK_COMPLETED, pipeline.Status)
+ })
+ fmt.Println("======DONE======")
+}
diff --git a/backend/test/e2e/manual/gitlab/models.go
b/backend/test/e2e/manual/gitlab/models.go
new file mode 100644
index 000000000..63f3ffbe1
--- /dev/null
+++ b/backend/test/e2e/manual/gitlab/models.go
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package gitlab
+
+type TestConfig struct {
+ Token string
+ Projects []string
+}
diff --git a/backend/test/e2e/manual/pagerduty/models.go
b/backend/test/e2e/manual/pagerduty/models.go
new file mode 100644
index 000000000..c22634c36
--- /dev/null
+++ b/backend/test/e2e/manual/pagerduty/models.go
@@ -0,0 +1,26 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package pagerduty
+
+import "time"
+
+type TestConfig struct {
+ Token string
+ TimeSince *time.Time
+ Services []string
+}
diff --git a/backend/test/e2e/manual/pagerduty/pagerduty_test.go
b/backend/test/e2e/manual/pagerduty/pagerduty_test.go
new file mode 100644
index 000000000..d8257e2c5
--- /dev/null
+++ b/backend/test/e2e/manual/pagerduty/pagerduty_test.go
@@ -0,0 +1,164 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package pagerduty
+
+import (
+ "fmt"
+ "github.com/apache/incubator-devlake/core/config"
+ "github.com/apache/incubator-devlake/core/models"
+ "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ "github.com/apache/incubator-devlake/plugins/pagerduty/impl"
+ pluginmodels
"github.com/apache/incubator-devlake/plugins/pagerduty/models"
+ "github.com/apache/incubator-devlake/test/helper"
+ "github.com/stretchr/testify/require"
+ "testing"
+ "time"
+)
+
+const pluginName = "pagerduty"
+
+func TestPagerDutyPlugin(t *testing.T) {
+ cfg := helper.GetTestConfig[TestConfig]()
+ client := helper.ConnectLocalServer(t, &helper.LocalClientConfig{
+ ServerPort: 8089,
+ DbURL: config.GetConfig().GetString("E2E_DB_URL"),
+ CreateServer: true,
+ DropDb: false,
+ TruncateDb: true,
+ Plugins: map[string]plugin.PluginMeta{
+ pluginName: &impl.PagerDuty{},
+ },
+ })
+ client.SetTimeout(0)
+ client.SetPipelineTimeout(0)
+ connection := createConnection(cfg, client)
+ t.Run("blueprint v200", func(t *testing.T) {
+ serviceScopes := helper.RemoteScopesOutput{}
+ var scopeData []any
+ for {
+ serviceScopes =
client.RemoteScopes(helper.RemoteScopesQuery{
+ PluginName: pluginName,
+ ConnectionId: connection.ID,
+ PageToken: serviceScopes.NextPageToken,
+ Params: nil,
+ })
+ for _, remoteScope := range serviceScopes.Children {
+ if remoteScope.Type == "scope" {
+ data :=
helper.Cast[pluginmodels.Service](remoteScope.Data)
+ for _, serviceName := range
cfg.Services {
+ if serviceName == data.Name {
+ scopeData =
append(scopeData, &data)
+ }
+ }
+ }
+ }
+ if serviceScopes.NextPageToken == "" {
+ break
+ }
+ }
+ createdScopes :=
helper.Cast[[]*pluginmodels.Service](client.CreateScopes(pluginName,
connection.ID, scopeData...))
+ require.True(t, len(createdScopes) > 0)
+ uniqueString := time.Now().Format(time.RFC3339)
+ outputProject := createProject(client,
fmt.Sprintf("pagerduty-project-%s-%s", pluginName, uniqueString))
+ var bpScopes []*plugin.BlueprintScopeV200
+ for _, scope := range createdScopes {
+ bpScopes = append(bpScopes, &plugin.BlueprintScopeV200{
+ Id: scope.Id,
+ Name:
fmt.Sprintf("pagerduty-blueprint-v200-%s", uniqueString),
+ })
+ }
+ bp := client.CreateBasicBlueprintV2(connection.Name,
&helper.BlueprintV2Config{
+ Connection: &plugin.BlueprintConnectionV200{
+ Plugin: pluginName,
+ ConnectionId: connection.ID,
+ Scopes: bpScopes,
+ },
+ TimeAfter: cfg.TimeSince,
+ SkipOnFail: false,
+ ProjectName: outputProject.Name,
+ })
+ // get the project ... should have a reference to the blueprint
now
+ outputProject = client.GetProject(outputProject.Name)
+ require.Equal(t, bp.Name, outputProject.Blueprint.Name)
+ fmt.Printf("=========================Triggering blueprint for
project %s =========================\n", outputProject.Name)
+ pipeline := client.TriggerBlueprint(bp.ID)
+ require.Equal(t, models.TASK_COMPLETED, pipeline.Status)
+ createdScopesList := client.ListScopes(pluginName,
connection.ID, true)
+ require.True(t, len(createdScopesList) > 0)
+ for _, scope := range createdScopesList {
+ scopeCast :=
helper.Cast[pluginmodels.Service](scope.Scope)
+ fmt.Printf("Deleting scope %s\n", scopeCast.Id)
+ client.DeleteScope(pluginName, connection.ID,
scopeCast.Id, false)
+ fmt.Printf("Deleted scope %s\n", scopeCast.Id)
+ }
+ })
+ fmt.Println("======DONE======")
+}
+
+func createConnection(cfg TestConfig, client *helper.DevlakeClient)
*helper.Connection {
+ conn := pluginmodels.PagerDutyConn{
+ RestConnection: api.RestConnection{
+ Endpoint: "https://api.pagerduty.com",
+ Proxy: "",
+ RateLimitPerHour: 0,
+ },
+ PagerDutyAccessToken: pluginmodels.PagerDutyAccessToken{
+ Token: cfg.Token,
+ },
+ }
+ client.TestConnection(pluginName, conn)
+ connections := client.ListConnections(pluginName)
+ for _, connection := range connections {
+ if connection.Name == "pagerduty-conn" {
+ return connection
+ }
+ }
+ return client.CreateConnection(pluginName,
pluginmodels.PagerDutyConnection{
+ BaseConnection: api.BaseConnection{
+ Name: "pagerduty-conn",
+ },
+ PagerDutyConn: conn,
+ })
+}
+
+func createProject(client *helper.DevlakeClient, projectName string)
models.ApiOutputProject {
+ projects := client.ListProjects()
+ for _, project := range projects.Projects {
+ if project.Name == projectName {
+ outputProject := client.GetProject(projectName)
+ return outputProject
+ }
+ }
+ outputProject := client.CreateProject(&helper.ProjectConfig{
+ ProjectName: projectName,
+ EnableDora: true,
+ })
+ return outputProject
+}
+
+func getTime(timeString string) *time.Time {
+ if timeString == "" {
+ return &time.Time{}
+ }
+ t, err := time.Parse("2006-01-02T15:04:05Z", timeString)
+ if err != nil {
+ panic(err)
+ }
+ return &t
+}
diff --git a/backend/test/e2e/remote/helper.go
b/backend/test/e2e/remote/helper.go
index 8af1da556..11999e8ad 100644
--- a/backend/test/e2e/remote/helper.go
+++ b/backend/test/e2e/remote/helper.go
@@ -91,7 +91,7 @@ func CreateTestConnection(client *helper.DevlakeClient)
*helper.Connection {
}
func CreateTestScope(client *helper.DevlakeClient, config *FakeScopeConfig,
connectionId uint64) *FakeProject {
- scopes := helper.Cast[[]FakeProject](client.CreateScope(PLUGIN_NAME,
+ scopes := helper.Cast[[]FakeProject](client.CreateScopes(PLUGIN_NAME,
connectionId,
FakeProject{
Id: "p1",
diff --git a/backend/test/helper/api.go b/backend/test/helper/api.go
index 2bca9019d..78d5837d2 100644
--- a/backend/test/helper/api.go
+++ b/backend/test/helper/api.go
@@ -158,7 +158,7 @@ func (d *DevlakeClient) ListProjects()
apiProject.PaginatedProjects {
}, http.MethodGet, fmt.Sprintf("%s/projects", d.Endpoint), nil, nil)
}
-func (d *DevlakeClient) CreateScope(pluginName string, connectionId uint64,
scopes ...any) any {
+func (d *DevlakeClient) CreateScopes(pluginName string, connectionId uint64,
scopes ...any) any {
request := map[string]any{
"data": scopes,
}
diff --git a/backend/test/helper/client.go b/backend/test/helper/client.go
index 086970e11..7c0f6a5ea 100644
--- a/backend/test/helper/client.go
+++ b/backend/test/helper/client.go
@@ -23,6 +23,11 @@ import (
"encoding/json"
goerror "errors"
"fmt"
+ "github.com/apache/incubator-devlake/core/dal"
+ dora "github.com/apache/incubator-devlake/plugins/dora/impl"
+ org "github.com/apache/incubator-devlake/plugins/org/impl"
+ refdiff "github.com/apache/incubator-devlake/plugins/refdiff/impl"
+ remotePlugin
"github.com/apache/incubator-devlake/server/services/remote/plugin"
"io"
"math"
"net/http"
@@ -32,11 +37,6 @@ import (
"testing"
"time"
- "github.com/apache/incubator-devlake/core/dal"
- dora "github.com/apache/incubator-devlake/plugins/dora/impl"
- org "github.com/apache/incubator-devlake/plugins/org/impl"
- remotePlugin
"github.com/apache/incubator-devlake/server/services/remote/plugin"
-
"github.com/apache/incubator-devlake/core/config"
corectx "github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
@@ -264,7 +264,7 @@ func (d *DevlakeClient) initPlugins(cfg *LocalClientConfig)
{
// default plugins
cfg.Plugins["org"] = org.Org{}
cfg.Plugins["dora"] = dora.Dora{}
-
+ cfg.Plugins["refdiff"] = refdiff.RefDiff{}
// register and init plugins
for name, p := range cfg.Plugins {
require.NoError(d.testCtx, plugin.RegisterPlugin(name, p))
@@ -373,7 +373,7 @@ func sendHttpRequest[Res any](t *testing.T, timeout
time.Duration, debug debugIn
return false, errors.Convert(err)
}
response.Close = true
- return false,
errors.HttpStatus(response.StatusCode).New(fmt.Sprintf("unexpected http status
code: %d", response.StatusCode))
+ return false,
errors.HttpStatus(response.StatusCode).New(fmt.Sprintf("unexpected http status
code calling [%s] %s: %d", httpMethod, endpoint, response.StatusCode))
}
b, _ = io.ReadAll(response.Body)
if err = json.Unmarshal(b, &result); err != nil {
diff --git a/backend/test/helper/models.go b/backend/test/helper/models.go
index a95bfb263..ad49c50c8 100644
--- a/backend/test/helper/models.go
+++ b/backend/test/helper/models.go
@@ -18,6 +18,7 @@ limitations under the License.
package helper
import (
+ "github.com/apache/incubator-devlake/core/config"
"github.com/apache/incubator-devlake/core/models"
"time"
@@ -91,3 +92,12 @@ type SearchRemoteScopesQuery struct {
PageSize int
Params map[string]string
}
+
+func SetTestConfig[T any](t T) {
+ config.GetConfig().Set("TEST_CONFIG", t)
+}
+
+func GetTestConfig[T any]() T {
+ raw := config.GetConfig().Get("TEST_CONFIG")
+ return raw.(T)
+}
diff --git a/backend/test/helper/utils.go b/backend/test/helper/utils.go
index 479fcd534..7bf603642 100644
--- a/backend/test/helper/utils.go
+++ b/backend/test/helper/utils.go
@@ -23,6 +23,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "reflect"
"strings"
"github.com/apache/incubator-devlake/core/plugin"
@@ -76,6 +77,15 @@ func Cast[T any](m any) T {
return *t
}
+func Contains[T any](list []T, elem any) bool {
+ for _, x := range list {
+ if reflect.DeepEqual(x, elem) {
+ return true
+ }
+ }
+ return false
+}
+
func readFile(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {