Skip to content

Commit

Permalink
add ignore mock files
Browse files Browse the repository at this point in the history
Signed-off-by: Stephanie <[email protected]>
  • Loading branch information
yangcao77 committed Jul 25, 2023
2 parents 6316eab + 77a3f5b commit 1f4a971
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 59 deletions.
63 changes: 36 additions & 27 deletions cdq-analysis/pkg/componentdetectionquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type K8sInfoClient struct {

// CDQ analyzer
// return values are for testing purpose
func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfilePath, dockerfilePath, URL, Revision, DevfileRegistryURL string, isDevfilePresent, isDockerfilePresent bool) (map[string][]byte, map[string]string, map[string]string, map[string][]int, error) {
func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfilePath, dockerfilePath, URL, Revision, DevfileRegistryURL string, isDevfilePresent, isDockerfilePresent bool) (map[string][]byte, map[string]string, map[string]string, map[string][]int, string, error) {
log := k.Log
var clonePath, componentPath string
alizerClient := AlizerClient{}
Expand All @@ -54,18 +54,46 @@ func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfil
context = "./"
}

clonePath, err = CreateTempPath(name, Fs)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to create a temp path %s for cloning %v", clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, "", err
}

err = CloneRepo(clonePath, URL, Revision, gitToken)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to clone repo %s to path %s, exiting reconcile loop %v", URL, clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, "", err
}
log.Info(fmt.Sprintf("cloned from %s to path %s... %v", URL, clonePath, namespace))
componentPath = clonePath
if context != "" {
componentPath = path.Join(clonePath, context)
}

if Revision == "" {
Revision, err = GetBranchFromRepo(componentPath)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to clone repo %s to path %s, exiting reconcile loop %v", URL, clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, "", err
}
}

isMultiComponent := false
if isDevfilePresent {
updatedLink, err := UpdateGitLink(URL, Revision, path.Join(context, devfilePath))
if err != nil {
log.Error(err, fmt.Sprintf("Unable to update the devfile link for CDQ %v... %v", name, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
shouldIgnoreDevfile, devfileBytes, err := ValidateDevfile(log, updatedLink)
if err != nil {
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
if shouldIgnoreDevfile {
isDevfilePresent = false
Expand All @@ -81,25 +109,6 @@ func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfil
dockerfileContextMap[context] = dockerfilePath
}

clonePath, err = CreateTempPath(name, Fs)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to create a temp path %s for cloning %v", clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
}

err = CloneRepo(clonePath, URL, Revision, gitToken)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to clone repo %s to path %s, exiting reconcile loop %v", URL, clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
}
log.Info(fmt.Sprintf("cloned from %s to path %s... %v", URL, clonePath, namespace))
componentPath = clonePath
if context != "" {
componentPath = path.Join(clonePath, context)
}

if !isDockerfilePresent {
log.Info(fmt.Sprintf("Unable to find devfile, Dockerfile or Containerfile under root directory, run Alizer to detect components... %v", namespace))

Expand All @@ -108,7 +117,7 @@ func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfil
if err != nil {
log.Error(err, fmt.Sprintf("Unable to detect components using Alizer for repo %v, under path %v... %v ", URL, componentPath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
log.Info(fmt.Sprintf("components detected %v... %v", components, namespace))
// If no devfile and no Dockerfile or Containerfile present in the root
Expand All @@ -128,7 +137,7 @@ func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfil
if _, ok := err.(*NoDevfileFound); !ok {
log.Error(err, fmt.Sprintf("Unable to find devfile(s) in repo %s due to an error %s, exiting reconcile loop %v", URL, err.Error(), namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
}
} else {
Expand All @@ -137,20 +146,20 @@ func CloneAndAnalyze(k K8sInfoClient, gitToken, namespace, name, context, devfil
if err != nil {
log.Error(err, fmt.Sprintf("Unable to analyze path %s for a devfile, Dockerfile or Containerfile %v", componentPath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
}

if isExist, _ := IsExisting(Fs, clonePath); isExist {
if err := Fs.RemoveAll(clonePath); err != nil {
log.Error(err, fmt.Sprintf("Unable to remove the clonepath %s %v", clonePath, namespace))
k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, err)
return nil, nil, nil, nil, err
return nil, nil, nil, nil, "", err
}
}

k.SendBackDetectionResult(devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, name, namespace, nil)
return devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, nil
return devfilesMap, devfilesURLMap, dockerfileContextMap, componentPortsMap, Revision, nil
}

func (k K8sInfoClient) SendBackDetectionResult(devfilesMap map[string][]byte, devfilesURLMap map[string]string, dockerfileContextMap map[string]string, componentPortsMap map[string][]int, name, namespace string, completeError error) {
Expand Down
10 changes: 9 additions & 1 deletion cdq-analysis/pkg/componentdetectionquery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func TestCloneAndAnalyze(t *testing.T) {
wantDevfilesURLMap map[string]string
wantDockerfileContextMap map[string]string
wantComponentsPortMap map[string][]int
wantBranch string
}{
{
testCase: "repo with devfile - should successfully detect spring component",
Expand All @@ -113,6 +114,7 @@ func TestCloneAndAnalyze(t *testing.T) {
},
wantDockerfileContextMap: map[string]string{},
wantComponentsPortMap: map[string][]int{},
wantBranch: "main",
},
{
testCase: "repo without devfile and dockerfile - should successfully detect spring component",
Expand All @@ -132,6 +134,7 @@ func TestCloneAndAnalyze(t *testing.T) {
wantComponentsPortMap: map[string][]int{
"./": {8081},
},
wantBranch: "main",
},
{
testCase: "private repo - should error out with no token provided",
Expand Down Expand Up @@ -185,6 +188,7 @@ func TestCloneAndAnalyze(t *testing.T) {
wantComponentsPortMap: map[string][]int{
"devfile-sample-nodejs-basic": {3000},
},
wantBranch: "main",
},
{
testCase: "should successfully detect single component when context is provided",
Expand All @@ -206,12 +210,13 @@ func TestCloneAndAnalyze(t *testing.T) {
wantDockerfileContextMap: map[string]string{
"devfile-sample-nodejs-basic": "https://raw.githubusercontent.com/nodeshift-starters/devfile-sample/main/Dockerfile",
},
wantBranch: "main",
},
}

for _, tt := range tests {
t.Run(tt.testCase, func(t *testing.T) {
devfilesMap, devfilesURLMap, dockerfileContextMap, componentsPortMap, err := CloneAndAnalyze(k8sClient, tt.gitToken, namespaceName, compName, tt.context, tt.devfilePath, "", tt.URL, tt.Revision, tt.DevfileRegistryURL, tt.isDevfilePresent, tt.isDockerfilePresent)
devfilesMap, devfilesURLMap, dockerfileContextMap, componentsPortMap, branch, err := CloneAndAnalyze(k8sClient, tt.gitToken, namespaceName, compName, tt.context, tt.devfilePath, "", tt.URL, tt.Revision, tt.DevfileRegistryURL, tt.isDevfilePresent, tt.isDockerfilePresent)
if (err != nil) != (tt.wantErr != "") {
t.Errorf("got unexpected error %v", err)
} else if err == nil {
Expand All @@ -238,6 +243,9 @@ func TestCloneAndAnalyze(t *testing.T) {
if !reflect.DeepEqual(componentsPortMap, tt.wantComponentsPortMap) {
t.Errorf("Expected componentsPortMap: %+v, Got: %+v", tt.wantComponentsPortMap, componentsPortMap)
}
if branch != tt.wantBranch {
t.Errorf("Expected branch: %+v, Got: %+v", tt.wantBranch, branch)
}
} else if err != nil {
assert.Regexp(t, tt.wantErr, err.Error(), "Error message should match")
}
Expand Down
18 changes: 18 additions & 0 deletions cdq-analysis/pkg/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ func CloneRepo(clonePath, repoURL string, revision string, token string) error {
return nil
}

// GetBranchFromRepo gets the current branch from the cloned repository
func GetBranchFromRepo(clonePath string) (string, error) {
// Command we want to run is: git rev-parse --abbrev-ref HEAD
c := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
c.Dir = clonePath

// Get the output of the command
branchBytes, err := c.CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to get the branch from the repo: %v", err)
}
branch := string(branchBytes)

// Remove newline characters potentially present
branch = strings.Split(branch, "\n")[0]
return branch, nil
}

// CurlEndpoint curls the endpoint and returns the response or an error if the response is a non-200 status
func CurlEndpoint(endpoint string) ([]byte, error) {
var respBytes []byte
Expand Down
53 changes: 53 additions & 0 deletions cdq-analysis/pkg/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,59 @@ func TestCloneRepo(t *testing.T) {
}
}

func TestGetBranchFromRepo(t *testing.T) {
os.Mkdir("/tmp/alreadyexistingdir", 0755)

tests := []struct {
name string
clonePath string
repo string
revision string
token string
wantErr bool
want string
}{
{
name: "Detect Successfully",
clonePath: "/tmp/testspringbootclone",
repo: "https://github.com/devfile-samples/devfile-sample-java-springboot-basic",
want: "main",
},
{
name: "Detect alternate branch Successfully",
clonePath: "/tmp/testspringbootclonealt",
repo: "https://github.com/devfile-samples/devfile-sample-java-springboot-basic",
revision: "testbranch",
want: "testbranch",
},
{
name: "Repo not exist",
clonePath: "FDSFSDFSDFSDFjsdklfjsdklfjs",
repo: "https://github.com/devfile-samples/devfile-sample-java-springboot-basic",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
os.RemoveAll(tt.clonePath)
if tt.name != "Repo not exist" {
CloneRepo(tt.clonePath, tt.repo, tt.revision, tt.token)
}

branch, err := GetBranchFromRepo(tt.clonePath)
if (err != nil) != tt.wantErr {
t.Errorf("TestGetBranchFromRepo() unexpected error: %v", err)
}
if err != nil {
if branch != tt.want {
t.Errorf("TestGetBranchFromRepo() unexpected branch, expected %v got %v", tt.want, branch)
}
}
})
}
}

func TestConvertGitHubURL(t *testing.T) {
tests := []struct {
name string
Expand Down
6 changes: 4 additions & 2 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
ignore:
- "api/v1alpha1/zz_generated.deepcopy.go" # generated file, does not need to be included in the coverage
- "pkg/spi/spi_mock.go" # mock file for testing
- "pkg/devfile/detect_mock.go" # mock file for testing
- "gitops/generate_mock.go" # mock file for testing
- "controllers/start_test_env.go" # setup of a test environment for unit and Pact tests
- "controllers/application_pact_test_state_handlers.go" # state handlers for the Pact tests
- "controllers/application_pact_test_utils.go" # utils file for the Pact tests
- "controllers/application_pact_test_utils.go" # utils file for the Pact tests
- "cdq-analysis/pkg/detect_mock.go" # mock file for testing
- "pkg/github/mock.go" # mock file for testing
- "pkg/github/token_moke.go" # mock file for testing
56 changes: 29 additions & 27 deletions controllers/componentdetectionquery_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,32 +159,6 @@ func (r *ComponentDetectionQueryReconciler) Reconcile(ctx context.Context, req c
return ctrl.Result{}, nil
}

if source.Revision == "" {
log.Info(fmt.Sprintf("Look for default branch of repo %s... %v", source.URL, req.NamespacedName))
metricsLabel := prometheus.Labels{"controller": cdqName, "tokenName": ghClient.TokenName, "operation": "GetDefaultBranchFromURL"}
metrics.ControllerGitRequest.With(metricsLabel).Inc()
source.Revision, err = ghClient.GetDefaultBranchFromURL(sourceURL, ctx)
metrics.HandleRateLimitMetrics(err, metricsLabel)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to get default branch of Github Repo %v, try to fall back to main branch... %v", source.URL, req.NamespacedName))
metricsLabel := prometheus.Labels{"controller": cdqName, "tokenName": ghClient.TokenName, "operation": "GetBranchFromURL"}
metrics.ControllerGitRequest.With(metricsLabel).Inc()
_, err := ghClient.GetBranchFromURL(sourceURL, ctx, "main")
if err != nil {
metrics.HandleRateLimitMetrics(err, metricsLabel)
log.Error(err, fmt.Sprintf("Unable to get main branch of Github Repo %v ... %v", source.URL, req.NamespacedName))
retErr := fmt.Errorf("unable to get default branch of Github Repo %v, try to fall back to main branch, failed to get main branch... %v", source.URL, req.NamespacedName)
r.SetCompleteConditionAndUpdateCR(ctx, req, &componentDetectionQuery, copiedCDQ, retErr)
return ctrl.Result{}, nil
} else {
source.Revision = "main"
}
}
}

// set in the CDQ spec
componentDetectionQuery.Spec.GitSource.Revision = source.Revision

if source.DevfileURL == "" {
isDockerfilePresent := false
isDevfilePresent := false
Expand Down Expand Up @@ -215,7 +189,8 @@ func (r *ComponentDetectionQueryReconciler) Reconcile(ctx context.Context, req c
CreateK8sJob: false,
}

devfilesMapReturned, devfilesURLMapReturned, dockerfileContextMapReturned, componentPortsMapReturned, err := cdqanalysis.CloneAndAnalyze(k8sInfoClient, gitToken, req.Namespace, req.Name, context, devfilePath, dockerfilePath, source.URL, source.Revision, r.DevfileRegistryURL, isDevfilePresent, isDockerfilePresent)
devfilesMapReturned, devfilesURLMapReturned, dockerfileContextMapReturned, componentPortsMapReturned, branch, err := cdqanalysis.CloneAndAnalyze(k8sInfoClient, gitToken, req.Namespace, req.Name, context, devfilePath, dockerfilePath, source.URL, source.Revision, r.DevfileRegistryURL, isDevfilePresent, isDockerfilePresent)
componentDetectionQuery.Spec.GitSource.Revision = branch
if err != nil {
log.Error(err, fmt.Sprintf("Error running cdq analysis... %v", req.NamespacedName))
r.SetCompleteConditionAndUpdateCR(ctx, req, &componentDetectionQuery, copiedCDQ, err)
Expand All @@ -229,6 +204,33 @@ func (r *ComponentDetectionQueryReconciler) Reconcile(ctx context.Context, req c
} else {
log.Info(fmt.Sprintf("devfile was explicitly specified at %s %v", source.DevfileURL, req.NamespacedName))

// For scenarios where a devfile is passed in, we still need to use the GH API for branch detection as we do not clone.
if source.Revision == "" {
log.Info(fmt.Sprintf("Look for default branch of repo %s... %v", source.URL, req.NamespacedName))
metricsLabel := prometheus.Labels{"controller": cdqName, "tokenName": ghClient.TokenName, "operation": "GetDefaultBranchFromURL"}
metrics.ControllerGitRequest.With(metricsLabel).Inc()
source.Revision, err = ghClient.GetDefaultBranchFromURL(sourceURL, ctx)
metrics.HandleRateLimitMetrics(err, metricsLabel)
if err != nil {
log.Error(err, fmt.Sprintf("Unable to get default branch of Github Repo %v, try to fall back to main branch... %v", source.URL, req.NamespacedName))
metricsLabel := prometheus.Labels{"controller": cdqName, "tokenName": ghClient.TokenName, "operation": "GetBranchFromURL"}
metrics.ControllerGitRequest.With(metricsLabel).Inc()
_, err := ghClient.GetBranchFromURL(sourceURL, ctx, "main")
if err != nil {
metrics.HandleRateLimitMetrics(err, metricsLabel)
log.Error(err, fmt.Sprintf("Unable to get main branch of Github Repo %v ... %v", source.URL, req.NamespacedName))
retErr := fmt.Errorf("unable to get default branch of Github Repo %v, try to fall back to main branch, failed to get main branch... %v", source.URL, req.NamespacedName)
r.SetCompleteConditionAndUpdateCR(ctx, req, &componentDetectionQuery, copiedCDQ, retErr)
return ctrl.Result{}, nil
} else {
source.Revision = "main"
}
}
}

// set in the CDQ spec
componentDetectionQuery.Spec.GitSource.Revision = source.Revision

shouldIgnoreDevfile, devfileBytes, err := cdqanalysis.ValidateDevfile(log, source.DevfileURL)
if err != nil {
// if a direct devfileURL is provided and errors out, we dont do an alizer detection
Expand Down
4 changes: 2 additions & 2 deletions controllers/componentdetectionquery_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ var _ = Describe("Component Detection Query controller", func() {

// index is 1 because of CDQ status condition Processing
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Status).Should(Equal(metav1.ConditionFalse))
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Message).Should(ContainSubstring("error getting devfile info from url: failed to retrieve"))
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Message).Should(ContainSubstring("failed to clone the repo: exit status 128"))

// Delete the specified Detection Query resource
deleteCompDetQueryCR(hasCompDetQueryLookupKey)
Expand Down Expand Up @@ -628,7 +628,7 @@ var _ = Describe("Component Detection Query controller", func() {

// index is 1 because of CDQ status condition Processing
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Status).Should(Equal(metav1.ConditionFalse))
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Message).Should(ContainSubstring("error getting devfile info from url: failed to retrieve"))
Expect(createdHasCompDetectionQuery.Status.Conditions[1].Message).Should(ContainSubstring("failed to clone the repo: exit status 128"))

// Delete the specified Detection Query resource
deleteCompDetQueryCR(hasCompDetQueryLookupKey)
Expand Down

0 comments on commit 1f4a971

Please sign in to comment.