Skip to content

Commit 5dedefe

Browse files
authored
Merge branch 'apache:main' into main
2 parents 95a73e8 + f271245 commit 5dedefe

File tree

7 files changed

+246
-27
lines changed

7 files changed

+246
-27
lines changed

backend/plugins/azuredevops_go/tasks/shared.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ func ExtractContToken(_ *api.RequestData, prevPageResponse *http.Response) (inte
109109
}
110110

111111
var cicdBuildResultRule = devops.ResultRule{
112-
Success: []string{succeeded},
113-
Failure: []string{canceled, failed, none, partiallySucceeded},
112+
Success: []string{succeeded, partiallySucceeded},
113+
Failure: []string{canceled, failed, none},
114114
Default: devops.RESULT_DEFAULT,
115115
}
116116

backend/plugins/jira/tasks/epic_collector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func CollectEpics(taskCtx plugin.SubTaskContext) errors.Error {
5151
data := taskCtx.GetData().(*JiraTaskData)
5252
logger := taskCtx.GetLogger()
5353
batchSize := 100
54-
if data.JiraServerInfo.DeploymentType == models.DeploymentServer && len(data.JiraServerInfo.VersionNumbers) == 3 && data.JiraServerInfo.VersionNumbers[0] <= 8 {
54+
if strings.EqualFold(string(data.JiraServerInfo.DeploymentType), string(models.DeploymentServer)) && len(data.JiraServerInfo.VersionNumbers) == 3 && data.JiraServerInfo.VersionNumbers[0] <= 8 {
5555
batchSize = 1
5656
}
5757
epicIterator, err := GetEpicKeysIterator(db, data, batchSize)
@@ -83,7 +83,7 @@ func CollectEpics(taskCtx plugin.SubTaskContext) errors.Error {
8383
}
8484

8585
// Choose API endpoint based on JIRA deployment type
86-
if data.JiraServerInfo.DeploymentType == models.DeploymentServer {
86+
if strings.EqualFold(string(data.JiraServerInfo.DeploymentType), string(models.DeploymentServer)) {
8787
logger.Info("Using api/2/search for JIRA Server")
8888
err = setupApiV2Collector(apiCollector, data, epicIterator, jql)
8989
} else {
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package tasks
19+
20+
import (
21+
"strings"
22+
"testing"
23+
24+
"github.com/apache/incubator-devlake/plugins/jira/models"
25+
)
26+
27+
func TestEpicCollectorBatchSizeLogic(t *testing.T) {
28+
tests := []struct {
29+
name string
30+
deploymentType models.DeploymentType
31+
versionNumbers []int
32+
expectedBatch int
33+
}{
34+
{
35+
name: "JIRA Server v8 should use batch size 1",
36+
deploymentType: models.DeploymentServer,
37+
versionNumbers: []int{8, 0, 0},
38+
expectedBatch: 1,
39+
},
40+
{
41+
name: "JIRA Server v7 should use batch size 1",
42+
deploymentType: models.DeploymentServer,
43+
versionNumbers: []int{7, 5, 0},
44+
expectedBatch: 1,
45+
},
46+
{
47+
name: "JIRA Server v9 should use default batch size",
48+
deploymentType: models.DeploymentServer,
49+
versionNumbers: []int{9, 0, 0},
50+
expectedBatch: 100,
51+
},
52+
{
53+
name: "JIRA Cloud should use default batch size",
54+
deploymentType: models.DeploymentCloud,
55+
versionNumbers: []int{8, 0, 0}, // Version shouldn't matter for cloud
56+
expectedBatch: 100,
57+
},
58+
{
59+
name: "Case insensitive server comparison",
60+
deploymentType: "server", // lowercase
61+
versionNumbers: []int{8, 0, 0},
62+
expectedBatch: 1,
63+
},
64+
{
65+
name: "Case insensitive cloud comparison",
66+
deploymentType: "CLOUD", // uppercase
67+
versionNumbers: []int{8, 0, 0},
68+
expectedBatch: 100,
69+
},
70+
{
71+
name: "Mixed case server comparison",
72+
deploymentType: "SeRvEr", // mixed case
73+
versionNumbers: []int{7, 0, 0},
74+
expectedBatch: 1,
75+
},
76+
{
77+
name: "JIRA Server with incomplete version numbers",
78+
deploymentType: models.DeploymentServer,
79+
versionNumbers: []int{8, 0}, // Only 2 elements instead of 3
80+
expectedBatch: 100,
81+
},
82+
{
83+
name: "JIRA Server with empty version numbers",
84+
deploymentType: models.DeploymentServer,
85+
versionNumbers: []int{},
86+
expectedBatch: 100,
87+
},
88+
}
89+
90+
for _, tt := range tests {
91+
t.Run(tt.name, func(t *testing.T) {
92+
// Test the batch size logic from CollectEpics function
93+
batchSize := 100
94+
95+
// Replicate the exact logic from CollectEpics
96+
if strings.EqualFold(string(tt.deploymentType), string(models.DeploymentServer)) &&
97+
len(tt.versionNumbers) == 3 &&
98+
tt.versionNumbers[0] <= 8 {
99+
batchSize = 1
100+
}
101+
102+
if batchSize != tt.expectedBatch {
103+
t.Errorf("Batch size for %s with version %v: got %d, want %d",
104+
tt.deploymentType, tt.versionNumbers, batchSize, tt.expectedBatch)
105+
}
106+
})
107+
}
108+
}
109+
110+
func TestEpicCollectorDeploymentTypeLogic(t *testing.T) {
111+
tests := []struct {
112+
name string
113+
deploymentType models.DeploymentType
114+
expectServer bool
115+
}{
116+
{
117+
name: "JIRA Server constant should be detected as server",
118+
deploymentType: models.DeploymentServer,
119+
expectServer: true,
120+
},
121+
{
122+
name: "JIRA Cloud constant should not be detected as server",
123+
deploymentType: models.DeploymentCloud,
124+
expectServer: false,
125+
},
126+
{
127+
name: "Lowercase server should be detected as server",
128+
deploymentType: "server",
129+
expectServer: true,
130+
},
131+
{
132+
name: "Uppercase SERVER should be detected as server",
133+
deploymentType: "SERVER",
134+
expectServer: true,
135+
},
136+
{
137+
name: "Mixed case SeRvEr should be detected as server",
138+
deploymentType: "SeRvEr",
139+
expectServer: true,
140+
},
141+
{
142+
name: "Lowercase cloud should not be detected as server",
143+
deploymentType: "cloud",
144+
expectServer: false,
145+
},
146+
{
147+
name: "Uppercase CLOUD should not be detected as server",
148+
deploymentType: "CLOUD",
149+
expectServer: false,
150+
},
151+
{
152+
name: "Mixed case ClOuD should not be detected as server",
153+
deploymentType: "ClOuD",
154+
expectServer: false,
155+
},
156+
}
157+
158+
for _, tt := range tests {
159+
t.Run(tt.name, func(t *testing.T) {
160+
// Test the deployment type logic from CollectEpics function
161+
// This replicates the exact comparison used in the collector
162+
isServer := strings.EqualFold(string(tt.deploymentType), string(models.DeploymentServer))
163+
164+
if isServer != tt.expectServer {
165+
t.Errorf("Deployment type detection for %s: got isServer=%v, want %v",
166+
tt.deploymentType, isServer, tt.expectServer)
167+
}
168+
})
169+
}
170+
}
171+
172+
func TestEpicCollectorApiEndpointSelection(t *testing.T) {
173+
tests := []struct {
174+
name string
175+
deploymentType models.DeploymentType
176+
expectedEndpoint string
177+
}{
178+
{
179+
name: "JIRA Server should use api/2/search",
180+
deploymentType: models.DeploymentServer,
181+
expectedEndpoint: "api/2/search",
182+
},
183+
{
184+
name: "JIRA Cloud should use api/3/search/jql",
185+
deploymentType: models.DeploymentCloud,
186+
expectedEndpoint: "api/3/search/jql",
187+
},
188+
{
189+
name: "Lowercase server should use api/2/search",
190+
deploymentType: "server",
191+
expectedEndpoint: "api/2/search",
192+
},
193+
{
194+
name: "Uppercase CLOUD should use api/3/search/jql",
195+
deploymentType: "CLOUD",
196+
expectedEndpoint: "api/3/search/jql",
197+
},
198+
}
199+
200+
for _, tt := range tests {
201+
t.Run(tt.name, func(t *testing.T) {
202+
// Test the API endpoint selection logic from CollectEpics function
203+
var selectedEndpoint string
204+
205+
if strings.EqualFold(string(tt.deploymentType), string(models.DeploymentServer)) {
206+
selectedEndpoint = "api/2/search"
207+
} else {
208+
selectedEndpoint = "api/3/search/jql"
209+
}
210+
211+
if selectedEndpoint != tt.expectedEndpoint {
212+
t.Errorf("API endpoint selection for %s: got %s, want %s",
213+
tt.deploymentType, selectedEndpoint, tt.expectedEndpoint)
214+
}
215+
})
216+
}
217+
}

backend/plugins/jira/tasks/issue_collector.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"io"
2424
"net/http"
2525
"net/url"
26+
"strings"
2627
"time"
2728

2829
"github.com/apache/incubator-devlake/core/dal"
@@ -172,7 +173,7 @@ func getTimeZone(taskCtx plugin.SubTaskContext) (*time.Location, errors.Error) {
172173
var resp *http.Response
173174
var path string
174175
var query url.Values
175-
if data.JiraServerInfo.DeploymentType == models.DeploymentServer {
176+
if strings.EqualFold(string(data.JiraServerInfo.DeploymentType), string(models.DeploymentServer)) {
176177
path = "api/2/user"
177178
query = url.Values{"username": []string{conn.Username}}
178179
} else {

backend/plugins/webhook/api/deployments.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ import (
3939
)
4040

4141
type WebhookDeploymentReq struct {
42-
Id string `mapstructure:"id" validate:"required"`
43-
DisplayTitle string `mapstructure:"displayTitle"`
44-
Result string `mapstructure:"result"`
45-
Environment string `validate:"omitempty,oneof=PRODUCTION STAGING TESTING DEVELOPMENT"`
46-
Name string `mapstructure:"name"`
42+
Id string `mapstructure:"id" validate:"required"`
43+
DisplayTitle string `mapstructure:"displayTitle"`
44+
Result string `mapstructure:"result"`
45+
Environment string `validate:"omitempty,oneof=PRODUCTION STAGING TESTING DEVELOPMENT"`
46+
OriginalEnvironment string `mapstructure:"originalEnvironment"`
47+
Name string `mapstructure:"name"`
4748
// DeploymentCommits is used for multiple commits in one deployment
4849
DeploymentCommits []WebhookDeploymentCommitReq `mapstructure:"deploymentCommits" validate:"omitempty,dive"`
4950
CreatedDate *time.Time `mapstructure:"createdDate"`
@@ -219,7 +220,7 @@ func CreateDeploymentAndDeploymentCommits(connection *models.WebhookConnection,
219220
DisplayTitle: commit.DisplayTitle,
220221
RepoUrl: commit.RepoUrl,
221222
Environment: request.Environment,
222-
OriginalEnvironment: request.Environment,
223+
OriginalEnvironment: request.OriginalEnvironment,
223224
RefName: commit.RefName,
224225
CommitSha: commit.CommitSha,
225226
CommitMsg: commit.CommitMsg,

backend/python/plugins/azuredevops/azuredevops/streams/builds.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def convert(self, b: Build, ctx: Context):
5252
elif b.result == Build.BuildResult.Failed:
5353
result = devops.CICDResult.FAILURE
5454
elif b.result == Build.BuildResult.PartiallySucceeded:
55-
result = devops.CICDResult.FAILURE
55+
result = devops.CICDResult.SUCCESS
5656
elif b.result == Build.BuildResult.Succeeded:
5757
result = devops.CICDResult.SUCCESS
5858

0 commit comments

Comments
 (0)