Skip to content

Commit f94a0de

Browse files
authored
Merge pull request #980 from Checkmarx/Bug/Fix-contributor-cout-bitbucket-corrupted-repos
Fix handle corrupted repos In BitBucket utils contributor-count (AST-76750)
2 parents 5e83af0 + 7d551bb commit f94a0de

File tree

3 files changed

+135
-1
lines changed

3 files changed

+135
-1
lines changed

internal/commands/util/usercount/bitbucketserver/bitbucket-server.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ func searchRepos(
203203
*bitbucketServerToken,
204204
)
205205
if err != nil {
206-
return nil, nil, nil, err
206+
log.Printf("Skipping repository %s/%s: Repository is corrupted (error: %v)", project, repo, err)
207+
continue
207208
}
208209
totalCommits = append(totalCommits, commits...)
209210

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package bitbucketserver
2+
3+
import (
4+
"bytes"
5+
"log"
6+
"testing"
7+
8+
"github.com/checkmarx/ast-cli/internal/wrappers/mock"
9+
"gotest.tools/assert"
10+
)
11+
12+
func TestSearchReposWithCorruptedRepositories(t *testing.T) {
13+
mockWrapper := mock.WrapperBitbucketServer{
14+
CorruptedRepos: []string{"repo-2"},
15+
}
16+
17+
var logOutput bytes.Buffer
18+
log.SetOutput(&logOutput)
19+
defer log.SetOutput(nil)
20+
21+
project := "mock-project"
22+
repos := []string{"repo-1", "repo-2", "repo-3"}
23+
token := "mock-token"
24+
25+
views, viewsUsers, err := mockWrapper.SearchRepos(project, repos, token)
26+
27+
assert.NilError(t, err, "SearchRepos should not return an error")
28+
29+
assert.Equal(t, len(views), 2, "Only valid repositories should be processed")
30+
assert.Equal(t, views[0].Name, "mock-project/repo-1", "First repository name should match")
31+
assert.Equal(t, views[1].Name, "mock-project/repo-3", "Second repository name should match")
32+
33+
assert.Equal(t, len(viewsUsers), 2, "Each repository should have 1 contributor")
34+
assert.Equal(t, viewsUsers[0].Name, "mock-project/repo-1", "Contributor should match first repository")
35+
assert.Equal(t, viewsUsers[1].Name, "mock-project/repo-3", "Contributor should match second repository")
36+
37+
logStr := logOutput.String()
38+
assert.Assert(t, containsLog(logStr, "Skipping repository mock-project/repo-2: Repository is corrupted"), "Log should contain corrupted repository message")
39+
assert.Assert(t, containsLog(logStr, "Processed repository mock-project/repo-1"), "Log should confirm successful processing of repo-1")
40+
assert.Assert(t, containsLog(logStr, "Processed repository mock-project/repo-3"), "Log should confirm successful processing of repo-3")
41+
42+
t.Log("Captured Logs:")
43+
t.Log(logStr)
44+
}
45+
46+
func containsLog(logStr, expected string) bool {
47+
return bytes.Contains([]byte(logStr), []byte(expected))
48+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package mock
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/checkmarx/ast-cli/internal/wrappers/bitbucketserver"
8+
"github.com/pkg/errors"
9+
)
10+
11+
type WrapperBitbucketServer struct {
12+
CorruptedRepos []string
13+
}
14+
15+
type RepositoryView struct {
16+
Name string `json:"name"`
17+
UniqueContributors uint64 `json:"unique_contributors"`
18+
}
19+
20+
type UserView struct {
21+
Name string `json:"name"`
22+
UniqueContributorsUsername string `json:"unique_contributors_username"`
23+
}
24+
25+
func (m WrapperBitbucketServer) GetCommits(bitBucketURL, projectKey, repoSlug, bitBucketPassword string) ([]bitbucketserver.Commit, error) {
26+
for _, corruptedRepo := range m.CorruptedRepos {
27+
if repoSlug == corruptedRepo {
28+
return nil, errors.New(fmt.Sprintf("repository %s is corrupted", repoSlug))
29+
}
30+
}
31+
return []bitbucketserver.Commit{
32+
{
33+
Author: bitbucketserver.Author{Name: "Mock Author", Email: "[email protected]"},
34+
AuthorTimestamp: 1625078400000,
35+
},
36+
}, nil
37+
}
38+
func (m WrapperBitbucketServer) GetRepositories(bitBucketURL, projectKey, bitBucketPassword string) ([]bitbucketserver.Repo, error) {
39+
return []bitbucketserver.Repo{
40+
{Slug: "repo-1", Name: "Repository 1"},
41+
{Slug: "repo-2", Name: "Repository 2"},
42+
{Slug: "repo-3", Name: "Repository 3"},
43+
}, nil
44+
}
45+
func (m WrapperBitbucketServer) GetProjects(bitBucketURL, bitBucketPassword string) ([]string, error) {
46+
// Return mock projects
47+
return []string{"project-1", "project-2"}, nil
48+
}
49+
func (m WrapperBitbucketServer) SearchRepos(
50+
project string,
51+
repos []string,
52+
bitBucketToken string,
53+
) ([]RepositoryView, []UserView, error) {
54+
var views []RepositoryView
55+
var viewsUsers []UserView
56+
for _, repo := range repos {
57+
_, err := m.GetCommits("mock-url", project, repo, bitBucketToken)
58+
if err != nil {
59+
log.Printf("Skipping repository %s/%s: Repository is corrupted (error: %v)", project, repo, err)
60+
continue
61+
}
62+
log.Printf("Processed repository %s/%s", project, repo)
63+
64+
uniqueContributors := map[string]string{
65+
"[email protected]": "Mock Author",
66+
}
67+
views = append(
68+
views,
69+
RepositoryView{
70+
Name: fmt.Sprintf("%s/%s", project, repo),
71+
UniqueContributors: uint64(len(uniqueContributors)),
72+
},
73+
)
74+
for email, name := range uniqueContributors {
75+
viewsUsers = append(
76+
viewsUsers,
77+
UserView{
78+
Name: fmt.Sprintf("%s/%s", project, repo),
79+
UniqueContributorsUsername: fmt.Sprintf("%s - %s", name, email),
80+
},
81+
)
82+
}
83+
}
84+
return views, viewsUsers, nil
85+
}

0 commit comments

Comments
 (0)