From da050c780dedd2e5229117cc63de0671798a1c85 Mon Sep 17 00:00:00 2001 From: Maysun Faisal <31771087+maysunfaisal@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:43:15 -0500 Subject: [PATCH] [DEVHAS-611] Update Component create metrics for better data (#441) * Update metrics only if current err state is different to the prev Signed-off-by: Maysun J Faisal * Remove metrics tracking for Gitops due to future commitments Signed-off-by: Maysun J Faisal --------- Signed-off-by: Maysun J Faisal --- controllers/component_controller.go | 118 +++---- controllers/component_controller_test.go | 314 +++++++++--------- controllers/component_controller_unit_test.go | 30 +- pkg/github/errors.go | 34 ++ pkg/github/github.go | 7 +- pkg/github/github_test.go | 15 - pkg/metrics/application.go | 60 ++++ pkg/metrics/component.go | 103 ++++++ pkg/metrics/component_test.go | 93 ++++++ pkg/metrics/git.go | 75 +++++ pkg/metrics/gitops.go | 40 +++ pkg/metrics/metrics.go | 159 +-------- 12 files changed, 637 insertions(+), 411 deletions(-) create mode 100644 pkg/github/errors.go create mode 100644 pkg/metrics/application.go create mode 100644 pkg/metrics/component.go create mode 100644 pkg/metrics/component_test.go create mode 100644 pkg/metrics/git.go create mode 100644 pkg/metrics/gitops.go diff --git a/controllers/component_controller.go b/controllers/component_controller.go index 5c95ff752..682e6c83d 100644 --- a/controllers/component_controller.go +++ b/controllers/component_controller.go @@ -119,6 +119,8 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return ctrl.Result{}, err } + isCreateReconcile, prevErrCondition := checkForCreateReconcile(component) + // Get the Application CR hasApplication := appstudiov1alpha1.Application{} err = r.Get(ctx, types.NamespacedName{Name: component.Spec.Application, Namespace: component.Namespace}, &hasApplication) @@ -218,11 +220,6 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( log.Info(fmt.Sprintf("Starting reconcile loop for %v", req.NamespacedName)) - isCreateReconcile := checkForCreateReconcile(component) - if isCreateReconcile { - metrics.ComponentCreationTotalReqs.Inc() - } - // Check if GitOps generation has failed on a reconcile // Attempt to generate GitOps and set appropriate conditions accordingly isUpdateErrConditionPresent := false @@ -241,13 +238,13 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if isCreateReconcile { // Gate it with a Create reconcile flag check since this code is executed by both Create and Update reconciliation // user error in devfile, increment success metric - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } } else { if isCreateReconcile { // Gate it with a Create reconcile flag check since this code is executed by both Create and Update reconciliation // not a user error, increment fail metric - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) } } } @@ -259,6 +256,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err := r.generateGitops(ctx, ghClient, &component, compDevfileData); err != nil { errMsg := fmt.Sprintf("Unable to generate gitops resources for component %v", req.NamespacedName) log.Error(err, errMsg) + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) // We are not tracking Component failures for GitOps due to future planning _ = r.SetGitOpsGeneratedConditionAndUpdateCR(ctx, req, &component, fmt.Errorf("%v: %v", errMsg, err)) return ctrl.Result{}, err } else { @@ -286,7 +284,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { return ctrl.Result{}, err } - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded("", "") return ctrl.Result{}, nil } @@ -322,6 +320,13 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( _, err := ghClient.GetBranchFromURL(sourceURL, ctx, "main") if err != nil { metrics.HandleRateLimitMetrics(err, metricsLabel) + if _, ok := err.(*github.GitHubUserErr); ok { + // User error, so increment the "success" metric since we're tracking only system errors + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) + } else { + // Not a user error, increment fail metric + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) + } log.Error(err, fmt.Sprintf("Unable to get main branch of Github Repo %v ... %v", source.GitSource.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.GitSource.URL, req.NamespacedName) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, retErr) @@ -341,7 +346,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { // ConvertGitHubURL only returns user error metrics.ImportGitRepoSucceeded.Inc() - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to convert Github URL to raw format, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -351,7 +356,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // FindAndDownloadDevfile only returns user error metrics.ImportGitRepoSucceeded.Inc() if err != nil { - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to read the devfile from dir %s %v", gitURL, req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -367,10 +372,10 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // Increment the import git repo and component create failed metric on non-user errors if _, ok := err.(*cdqanalysis.NoDevfileFound); !ok { metrics.ImportGitRepoFailed.Inc() - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) } else { metrics.ImportGitRepoSucceeded.Inc() - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } log.Error(err, fmt.Sprintf("Unable to download from any known devfile locations from %s %v", gitURL, req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) @@ -381,7 +386,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( gitURL, err := cdqanalysis.ConvertGitHubURL(source.GitSource.URL, source.GitSource.Revision, context) if err != nil { // User error - so increment the "success" metric - since we're tracking only system errors - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to convert Github URL to raw format, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -394,7 +399,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } else if source.GitSource.DockerfileURL != "" { devfileData, err := devfile.CreateDevfileForDockerfileBuild(source.GitSource.DockerfileURL, "./", component.Name, component.Spec.Application) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to create devfile for Dockerfile build %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -402,7 +407,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( devfileBytes, err = yaml.Marshal(devfileData) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to marshal devfile, exiting reconcile loop %v", req.NamespacedName)) err = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) if err != nil { @@ -416,7 +421,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // Generate a stub devfile for the component devfileData, err := devfile.ConvertImageComponentToDevfile(component) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to convert the Image Component to a devfile %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -425,7 +430,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( devfileBytes, err = yaml.Marshal(devfileData) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to marshal devfile, exiting reconcile loop %v", req.NamespacedName)) err = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) if err != nil { @@ -446,10 +451,10 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { if _, ok := err.(*parserErrPkg.NonCompliantDevfile); ok { // user error in devfile, increment success metric - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } else { // not a user error, increment fail metric - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) } log.Error(err, fmt.Sprintf("Unable to parse the devfile from Component devfile location, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) @@ -465,10 +470,10 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { if _, ok := err.(*parserErrPkg.NonCompliantDevfile); ok { // user error in devfile, increment success metric - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } else { // not a user error, increment fail metric - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) } log.Error(err, fmt.Sprintf("Unable to parse the devfile from Component, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) @@ -480,13 +485,13 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { // Increment the Component create failed metric only on non-user errors if _, ok := err.(*NotSupported); ok { - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } else if _, ok := err.(*devfile.DevfileAttributeParse); ok { - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } else if _, ok := err.(*parserErrPkg.NonCompliantDevfile); ok { - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) } else { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) } log.Error(err, fmt.Sprintf("Unable to update the Component Devfile model %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) @@ -501,7 +506,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( hasAppDevfileData, err := cdqanalysis.ParseDevfileWithParserArgs(&devfileParser.ParserArgs{Data: []byte(hasApplication.Status.Devfile)}) if err != nil { // not a user error, increment fail metric - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to parse the devfile from Application, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -509,7 +514,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( yamlHASCompData, err := yaml.Marshal(compDevfileData) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to marshall the Component devfile, exiting reconcile loop %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -523,7 +528,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( log.Info(fmt.Sprintf("Adding the GitOps repository information to the status for component %v", req.NamespacedName)) err = setGitopsStatus(&component, hasAppDevfileData) if err != nil { - metrics.ComponentCreationFailed.Inc() + metrics.IncrementComponentCreationFailed(prevErrCondition, err.Error()) log.Error(err, fmt.Sprintf("Unable to retrieve gitops repository information for resource %v", req.NamespacedName)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, err) return ctrl.Result{}, err @@ -534,6 +539,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err := r.generateGitops(ctx, ghClient, &component, compDevfileData); err != nil { errMsg := fmt.Sprintf("Unable to generate gitops resources for component %v", req.NamespacedName) log.Error(err, errMsg) + metrics.IncrementComponentCreationSucceeded(prevErrCondition, err.Error()) // We are not tracking Component failures for GitOps due to future planning _ = r.SetGitOpsGeneratedConditionAndUpdateCR(ctx, req, &component, fmt.Errorf("%v: %v", errMsg, err)) _ = r.SetCreateConditionAndUpdateCR(ctx, req, &component, fmt.Errorf("%v: %v", errMsg, err)) return ctrl.Result{}, err @@ -549,7 +555,7 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if err != nil { return ctrl.Result{}, err } - metrics.ComponentCreationSucceeded.Inc() + metrics.IncrementComponentCreationSucceeded("", "") } } else { @@ -657,22 +663,14 @@ func (r *ComponentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *github.GitHubClient, component *appstudiov1alpha1.Component, compDevfileData data.DevfileData) error { log := ctrl.LoggerFrom(ctx) - isCreateReconcile := checkForCreateReconcile(*component) - gitOpsURL, gitOpsBranch, gitOpsContext, err := util.ProcessGitOpsStatus(component.Status.GitOps, ghClient.Token) if err != nil { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } return err } // Create a temp folder to create the gitops resources in tempDir, err := ioutils.CreateTempPath(component.Name, r.AppFS) if err != nil { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(err, "unable to create temp directory for GitOps resources due to error") ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) return fmt.Errorf("unable to create temp directory for GitOps resources due to error: %v", err) @@ -680,9 +678,6 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith deployAssociatedComponents, err := devfileParser.GetDeployComponents(compDevfileData) if err != nil { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(err, "unable to get deploy components") ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) return err @@ -690,18 +685,6 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith kubernetesResources, err := devfile.GetResourceFromDevfile(log, compDevfileData, deployAssociatedComponents, component.Name, component.Spec.Application, component.Spec.ContainerImage, "") if err != nil { - if _, ok := err.(*devfile.DevfileAttributeParse); ok && isCreateReconcile { - // Attribute parse error from Devfile is considered an user error - metrics.ComponentCreationSucceeded.Inc() - } else if _, ok := err.(*devfile.MissingOuterloop); ok && isCreateReconcile { - // If Devfile has no Outerloop component, it is considered an user error - metrics.ComponentCreationSucceeded.Inc() - } else if _, ok := err.(*parserErrPkg.NonCompliantDevfile); ok && isCreateReconcile { - // If Devfile is incompatible such as an issue with unmarshaling, it is considered an user error - metrics.ComponentCreationSucceeded.Inc() - } else if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(err, "unable to get kubernetes resources from the devfile outerloop components") ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) return err @@ -726,14 +709,7 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith unblockURL = fmt.Sprintf("%v/security/secret-scanning/unblock-secret/%v", component.Status.GitOps.RepositoryURL, token) log.Error(retErr, fmt.Sprintf("unable to generate gitops resources due to git push protecton error, follow the link to unblock the secret: %v", unblockURL)) } - if isCreateReconcile { - // Secret leak error is considered an user error - metrics.ComponentCreationSucceeded.Inc() - } } else { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(retErr, "unable to generate gitops resources due to error") } ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) @@ -756,14 +732,7 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith unblockURL = fmt.Sprintf("%v/security/secret-scanning/unblock-secret/%v", component.Status.GitOps.RepositoryURL, token) log.Error(retErr, fmt.Sprintf("unable to commit and push gitops resources due to git push protecton error, follow the link to unblock the secret: %v", unblockURL)) } - if isCreateReconcile { - // Secret leak error is considered an user error - metrics.ComponentCreationSucceeded.Inc() - } } else { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(retErr, "unable to commit and push gitops resources due to error") } ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) @@ -776,9 +745,6 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith metricsLabel := prometheus.Labels{"controller": componentName, "tokenName": ghClient.TokenName, "operation": "GetCommitIDFromRepo"} metrics.ControllerGitRequest.With(metricsLabel).Inc() if commitID, err = r.Generator.GetCommitIDFromRepo(r.AppFS, repoPath); err != nil { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(err, "") ioutils.RemoveFolderAndLogError(log, r.AppFS, tempDir) return err @@ -789,9 +755,6 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, ghClient *gith // Remove the temp folder that was created err = r.AppFS.RemoveAll(tempDir) if err != nil { - if isCreateReconcile { - metrics.ComponentCreationFailed.Inc() - } log.Error(err, "unable to remove temp dir") return err } @@ -904,15 +867,20 @@ func setForceGenerateGitopsAnnotation(component *appstudiov1alpha1.Component, va component.Annotations[forceGenerationAnnotation] = value } -func checkForCreateReconcile(component appstudiov1alpha1.Component) bool { +// checkForCreateReconcile checks if the Component is in Create state or an Update state. +// The err condition message is returned if it is in Create state. +func checkForCreateReconcile(component appstudiov1alpha1.Component) (bool, string) { + var errCondition string // Determine if this is a Create reconcile or an Update reconcile based on Conditions for _, condition := range component.Status.Conditions { if condition.Type == "Updated" { // If an Updated Condition is present, it means this is an Update reconcile - return false + return false, "" + } else if condition.Type == "Created" && condition.Reason == "Error" && condition.Status == metav1.ConditionFalse { + errCondition = condition.Message } } // If there are no Conditions or no Updated Condition, then this is a Create reconcile - return true + return true, errCondition } diff --git a/controllers/component_controller_test.go b/controllers/component_controller_test.go index 921cefc50..ad6ffc591 100644 --- a/controllers/component_controller_test.go +++ b/controllers/component_controller_test.go @@ -62,13 +62,13 @@ var _ = Describe("Component controller", func() { gitToken = "" //empty for public repo test ) - prometheus.MustRegister(metrics.ComponentCreationTotalReqs, metrics.ComponentCreationFailed, metrics.ComponentCreationSucceeded) + prometheus.MustRegister(metrics.GetComponentCreationTotalReqs(), metrics.GetComponentCreationFailed(), metrics.GetComponentCreationSucceeded()) Context("Create Component with basic field set", func() { It("Should create successfully and update the Application", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -166,9 +166,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -180,9 +180,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with basic field set including devfileURL", func() { It("Should create successfully on a valid url", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -271,9 +271,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -285,9 +285,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with basic field set including devfileURL", func() { It("Should error out on a bad url", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -336,9 +336,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) > beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -350,9 +350,9 @@ var _ = Describe("Component controller", func() { Context("Create a Component before an Application", func() { It("Should reconcile once the application is created", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -409,9 +409,9 @@ var _ = Describe("Component controller", func() { return len(createdHasComp.Status.Conditions) > 0 && createdHasComp.Status.Conditions[0].Reason == "OK" }, timeout40s, interval).Should(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASAppCR(types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace}) @@ -422,9 +422,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with other field set", func() { It("Should create successfully and update the Application", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -632,9 +632,9 @@ var _ = Describe("Component controller", func() { verifyHASComponentUpdates(hasCompUpdatedDevfile, checklist, nil) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -646,9 +646,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with built container image set", func() { It("Should create successfully", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -719,9 +719,9 @@ var _ = Describe("Component controller", func() { Expect(testutil.ToFloat64(metrics.ImportGitRepoSucceeded) > beforeImportGitRepoSucceeded).To(BeTrue()) Expect(testutil.ToFloat64(metrics.ImportGitRepoFailed) == beforeImportGitRepoFailed).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -733,9 +733,9 @@ var _ = Describe("Component controller", func() { Context("Component with invalid devfile", func() { It("Should fail and have proper failure condition set", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -794,9 +794,9 @@ var _ = Describe("Component controller", func() { Expect(errCondition.Status).Should(Equal(metav1.ConditionFalse)) Expect(errCondition.Message).Should(ContainSubstring("cannot unmarshal string into Go value of type map[string]interface")) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -815,9 +815,9 @@ var _ = Describe("Component controller", func() { // This first test will just use an invalid gitops repository url for the component Context("Component with gitops resource generation failure", func() { It("Should have proper failure condition set", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -892,9 +892,9 @@ var _ = Describe("Component controller", func() { Expect(gitopsCondition.Type).To(Equal("GitOpsResourcesGenerated")) Expect(gitopsCondition.Status).To(Equal(metav1.ConditionFalse)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -977,9 +977,9 @@ var _ = Describe("Component controller", func() { // The gitops generation should fail due to the gitops repository annotation missing Context("Component created with App with missing gitops repository", func() { It("Should fail since Application has no gitops repository", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) var err error ctx := context.Background() @@ -1047,9 +1047,9 @@ var _ = Describe("Component controller", func() { Expect(createdHasComp.Status.Conditions[len(createdHasComp.Status.Conditions)-1].Message).Should(ContainSubstring("unable to retrieve GitOps repository from Application CR devfile")) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) > beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1061,9 +1061,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with invalid git url", func() { It("Should fail with error", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1111,9 +1111,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1125,9 +1125,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with non-exist git url", func() { It("Should fail with error", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1183,9 +1183,9 @@ var _ = Describe("Component controller", func() { Expect(testutil.ToFloat64(metrics.ImportGitRepoSucceeded) > beforeImportGitRepoSucceeded).To(BeTrue()) Expect(testutil.ToFloat64(metrics.ImportGitRepoFailed) == beforeImportGitRepoFailed).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1197,9 +1197,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with invalid devfile url", func() { It("Should fail with error that devfile couldn't be unmarshalled", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1248,9 +1248,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1321,9 +1321,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with git secret field set to an invalid secret", func() { It("Should error out due parse error", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) // the secret exists but it's not a real one that we can use to access a live repo ctx := context.Background() @@ -1389,9 +1389,9 @@ var _ = Describe("Component controller", func() { Expect(strings.ToLower(createdHasComp.Status.Conditions[len(createdHasComp.Status.Conditions)-1].Message)).Should(ContainSubstring("error getting devfile info from url: failed to retrieve")) hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) > beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1403,9 +1403,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with private repo, but no devfile", func() { It("Should error out since no devfile exists", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1470,9 +1470,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) > beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1484,9 +1484,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with with context folder containing no devfile", func() { It("Should error out because a devfile cannot be found", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1534,9 +1534,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1640,9 +1640,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with Dockerfile URL set", func() { It("Should create successfully and update the Application", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1747,9 +1747,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1761,9 +1761,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with setGitOpsGeneration to true", func() { It("Should create successfully and not create the GitOps resources, and generate the resources once set.", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1810,9 +1810,9 @@ var _ = Describe("Component controller", func() { // Make sure the devfile model was properly set in Component Expect(createdComp.Status.Devfile).Should(Not(Equal(""))) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Now change skipGitOpsResourceGeneration to true and validate that the GitOps Resources are generated successfully (by validating the GitOpsResourcesGenerated status condition) createdComp.Spec.SkipGitOpsResourceGeneration = false @@ -1841,9 +1841,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with Dockerfile URL set for repo with devfile URL", func() { It("Should create successfully and override local Dockerfile URL references in the Devfile", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -1945,9 +1945,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -1960,9 +1960,9 @@ var _ = Describe("Component controller", func() { // Cannot test combined failure and recovery scenario since mock test uses the component name which can't be changed Context("Component with empty GitOps repository", func() { It("Should error out", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2045,9 +2045,9 @@ var _ = Describe("Component controller", func() { // Make sure the devfile model was properly set in Component Expect(createdHasComp.Status.Devfile).Should(Not(Equal(""))) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Update the devfile to empty to see if errors out createdHasComp.Status.Devfile = "" @@ -2079,9 +2079,9 @@ var _ = Describe("Component controller", func() { }) Context("Component with valid GitOps repository", func() { It("Should successfully update CR conditions and status", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2169,9 +2169,9 @@ var _ = Describe("Component controller", func() { // Make sure the devfile model was properly set in Component Expect(createdHasComp.Status.Devfile).Should(Not(Equal(""))) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -2182,9 +2182,9 @@ var _ = Describe("Component controller", func() { }) Context("force generate gitops resource", func() { It("Should successfully update CR conditions and status", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2229,9 +2229,9 @@ var _ = Describe("Component controller", func() { Expect(gitopsCondition.Type).To(Equal("GitOpsResourcesGenerated")) Expect(gitopsCondition.Status).To(Equal(metav1.ConditionTrue)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // set the annotation and update a spec to force enter the reconcile setForceGenerateGitopsAnnotation(createdHasComp, "true") @@ -2267,9 +2267,9 @@ var _ = Describe("Component controller", func() { Context("Create Private Component with basic field set", func() { It("Should create successfully and update the Application", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2384,9 +2384,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) @@ -2398,9 +2398,9 @@ var _ = Describe("Component controller", func() { Context("Create private and public Components for the same Application with basic field set", func() { It("Should create SPI FCR resource and associate it with only the private Component", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2578,9 +2578,9 @@ var _ = Describe("Component controller", func() { Expect(publicNameMatched).Should(Equal(true)) Expect(publicRepoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) == beforeCreateTotalReqs+2).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs+2).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) == beforeCreateTotalReqs+2).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs+2).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified public HASComp resource deleteHASCompCR(hasCompPublicLookupKey) @@ -2616,9 +2616,9 @@ var _ = Describe("Component controller", func() { Context("Create Private Component with basic field set and a private parent uri", func() { It("Should create successfully and update the Application", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2737,9 +2737,9 @@ var _ = Describe("Component controller", func() { Expect(nameMatched).Should(Equal(true)) Expect(repoLinkMatched).Should(Equal(true)) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Update Component createdHasComp.Spec.TargetPort = updatedPort @@ -2777,9 +2777,9 @@ var _ = Describe("Component controller", func() { Context("Create private Component for an Application with basic field set", func() { It("Should create SPI FCR resource and persist it even though the associated private Component is in an error state", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() applicationName := HASAppName + "27" @@ -2840,9 +2840,9 @@ var _ = Describe("Component controller", func() { Expect(createdHasPrivateComp.Status.Conditions[len(createdHasPrivateComp.Status.Conditions)-1].Reason).Should(Equal("Error")) Expect(strings.ToLower(createdHasPrivateComp.Status.Conditions[len(createdHasPrivateComp.Status.Conditions)-1].Message)).Should(ContainSubstring("error getting devfile")) - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) == beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) > beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) == beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) > beforeCreateFailedReqs).To(BeTrue()) hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} createdHasApp := &appstudiov1alpha1.Application{} @@ -2895,9 +2895,9 @@ var _ = Describe("Component controller", func() { Context("Create Component with basic field set including devfileURL", func() { It("Should error out on a devfile that has incompatible data and mark it as an user error on the metrics", func() { - beforeCreateTotalReqs := testutil.ToFloat64(metrics.ComponentCreationTotalReqs) - beforeCreateSucceedReqs := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailedReqs := testutil.ToFloat64(metrics.ComponentCreationFailed) + beforeCreateTotalReqs := testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) + beforeCreateSucceedReqs := testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) + beforeCreateFailedReqs := testutil.ToFloat64(metrics.GetComponentCreationFailed()) ctx := context.Background() @@ -2946,9 +2946,9 @@ var _ = Describe("Component controller", func() { hasAppLookupKey := types.NamespacedName{Name: applicationName, Namespace: HASAppNamespace} - Expect(testutil.ToFloat64(metrics.ComponentCreationTotalReqs) > beforeCreateTotalReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationSucceeded) > beforeCreateSucceedReqs).To(BeTrue()) - Expect(testutil.ToFloat64(metrics.ComponentCreationFailed) == beforeCreateFailedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationTotalReqs()) > beforeCreateTotalReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationSucceeded()) > beforeCreateSucceedReqs).To(BeTrue()) + Expect(testutil.ToFloat64(metrics.GetComponentCreationFailed()) == beforeCreateFailedReqs).To(BeTrue()) // Delete the specified HASComp resource deleteHASCompCR(hasCompLookupKey) diff --git a/controllers/component_controller_unit_test.go b/controllers/component_controller_unit_test.go index f09f67c63..fb4191cfb 100644 --- a/controllers/component_controller_unit_test.go +++ b/controllers/component_controller_unit_test.go @@ -572,6 +572,7 @@ func TestCheckForCreateReconcile(t *testing.T) { name string component appstudiov1alpha1.Component wantCreateReconcile bool + wantErrMsg string }{ { name: "Component with Create Condition", @@ -595,6 +596,29 @@ func TestCheckForCreateReconcile(t *testing.T) { }, wantCreateReconcile: true, }, + { + name: "Component with Create Condition in error state", + component: appstudiov1alpha1.Component{ + ObjectMeta: metav1.ObjectMeta{ + Name: "comp1", + }, + Spec: appstudiov1alpha1.ComponentSpec{ + ComponentName: "comp1", + }, + Status: appstudiov1alpha1.ComponentStatus{ + Conditions: []metav1.Condition{ + { + Type: "Created", + Status: metav1.ConditionFalse, + Reason: "Error", + Message: "Component create failed", + }, + }, + }, + }, + wantCreateReconcile: true, + wantErrMsg: "Component create failed", + }, { name: "Component with no Conditions", component: appstudiov1alpha1.Component{ @@ -640,11 +664,15 @@ func TestCheckForCreateReconcile(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := checkForCreateReconcile(tt.component) + got, gotErrMsg := checkForCreateReconcile(tt.component) if tt.wantCreateReconcile != got { t.Errorf("TestCheckForCreateReconcile error: expected %v, got %v", tt.wantCreateReconcile, got) } + + if tt.wantErrMsg != gotErrMsg { + t.Errorf("TestCheckForCreateReconcile error: expected error msg %v, got %v", tt.wantErrMsg, gotErrMsg) + } }) } diff --git a/pkg/github/errors.go b/pkg/github/errors.go new file mode 100644 index 000000000..3d37549e4 --- /dev/null +++ b/pkg/github/errors.go @@ -0,0 +1,34 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 github + +// GitHubUserErr is a user related error for the GitHub related operations +type GitHubUserErr struct { + Err string +} + +func (e *GitHubUserErr) Error() string { + return e.Err +} + +// GitHubSystemErr is a system related error for the GitHub related operations +type GitHubSystemErr struct { + Err string +} + +func (e *GitHubSystemErr) Error() string { + return e.Err +} diff --git a/pkg/github/github.go b/pkg/github/github.go index 9ffc1a1f8..e0f8c5882 100644 --- a/pkg/github/github.go +++ b/pkg/github/github.go @@ -143,15 +143,12 @@ func (g *GitHubClient) GetDefaultBranchFromURL(repoURL string, ctx context.Conte func (g *GitHubClient) GetBranchFromURL(repoURL string, ctx context.Context, branchName string) (*github.Branch, error) { repoName, orgName, err := GetRepoAndOrgFromURL(repoURL) if err != nil { - // User error - so increment the "success" metric - since we're tracking only system errors - metrics.ComponentCreationSucceeded.Inc() - return nil, err + return nil, &GitHubUserErr{Err: err.Error()} } branch, _, err := g.Client.Repositories.GetBranch(ctx, orgName, repoName, branchName, false) if err != nil || branch == nil { - metrics.ComponentCreationFailed.Inc() - return nil, fmt.Errorf("failed to get branch %s from repo %s under %s, error: %v", branchName, repoName, orgName, err) + return nil, &GitHubSystemErr{Err: fmt.Sprintf("failed to get branch %s from repo %s under %s, error: %v", branchName, repoName, orgName, err)} } return branch, nil diff --git a/pkg/github/github_test.go b/pkg/github/github_test.go index 162026aa6..e725e3e61 100644 --- a/pkg/github/github_test.go +++ b/pkg/github/github_test.go @@ -504,9 +504,6 @@ func TestGetBranchFromURL(t *testing.T) { Client: GetMockedClient(), } - beforeCreateSuccess := testutil.ToFloat64(metrics.ComponentCreationSucceeded) - beforeCreateFailed := testutil.ToFloat64(metrics.ComponentCreationFailed) - t.Run(tt.name, func(t *testing.T) { branch, err := mockedClient.GetBranchFromURL(tt.repoURL, context.Background(), tt.branchName) @@ -516,18 +513,6 @@ func TestGetBranchFromURL(t *testing.T) { if !tt.wantErr && *branch.Name != tt.branchName { t.Errorf("TestGetBranchFromURL() error: expected %v got %v", tt.branchName, *branch.Name) } - - if tt.wantErr { - if tt.name == "Unparseable URL" { - if testutil.ToFloat64(metrics.ComponentCreationSucceeded) <= beforeCreateSuccess { - t.Errorf("TestGetBranchFromURL() expected metric 'ComponentCreationSucceeded' to be incremented, beforeCreateSuccess %v and testutil.ToFloat64(metrics.ComponentCreationSucceeded) %v", beforeCreateSuccess, testutil.ToFloat64(metrics.ComponentCreationSucceeded)) - } - } else if tt.name == "Simple repo name" { - if testutil.ToFloat64(metrics.ComponentCreationFailed) <= beforeCreateFailed { - t.Errorf("TestGetBranchFromURL() expected metric 'ComponentCreationFailed' to be incremented, beforeCreateFailed %v and testutil.ToFloat64(metrics.ComponentCreationFailed) %v", beforeCreateFailed, testutil.ToFloat64(metrics.ComponentCreationFailed)) - } - } - } }) } } diff --git a/pkg/metrics/application.go b/pkg/metrics/application.go new file mode 100644 index 000000000..79a02e003 --- /dev/null +++ b/pkg/metrics/application.go @@ -0,0 +1,60 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 metrics + +import "github.com/prometheus/client_golang/prometheus" + +var ( + ApplicationDeletionTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_deletion_total", + Help: "Number of application deletion requests processed", + }, + ) + ApplicationDeletionFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_failed_deletion_total", + Help: "Number of failed application deletion requests", + }, + ) + + ApplicationDeletionSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_successful_deletion_total", + Help: "Number of successful application deletion requests", + }, + ) + + ApplicationCreationTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_creation_total", + Help: "Number of application creation requests processed", + }, + ) + ApplicationCreationFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_failed_creation_total", + Help: "Number of failed application creation requests", + }, + ) + + ApplicationCreationSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_application_successful_creation_total", + Help: "Number of successful application creation requests", + }, + ) +) diff --git a/pkg/metrics/component.go b/pkg/metrics/component.go new file mode 100644 index 000000000..21ce4bc53 --- /dev/null +++ b/pkg/metrics/component.go @@ -0,0 +1,103 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 metrics + +import ( + "strings" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + componentCreationTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_creation_total", + Help: "Number of component creation requests processed", + }, + ) + componentCreationFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_failed_creation_total", + Help: "Number of failed component creation requests", + }, + ) + + componentCreationSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_successful_creation_total", + Help: "Number of successful component creation requests", + }, + ) + + ComponentDeletionTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_deletion_total", + Help: "Number of component deletion requests processed", + }, + ) + ComponentDeletionFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_failed_deletion_total", + Help: "Number of failed component deletion requests", + }, + ) + + ComponentDeletionSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_component_successful_deletion_total", + Help: "Number of successful component deletion requests", + }, + ) +) + +// IncrementComponentCreationFailed increments the component creation failed metric. +// Pass in the new error to update the metric, otherwise it will be ignored. +func IncrementComponentCreationFailed(oldError, newError string) { + if newError != "" && (oldError == "" || !strings.Contains(oldError, newError)) { + // pair the componentCreationTotalReqs counter with componentCreationFailed because + // we dont want a situation where we increment componentCreationTotalReqs in the + // beginning of a reconcile, and we skip the componentCreationFailed metric because + // the errors are the same. Otherwise we will have a situation where neither the success + // nor the fail metric is increasing but the total request count is increasing. + componentCreationTotalReqs.Inc() + componentCreationFailed.Inc() + } +} + +func GetComponentCreationFailed() prometheus.Counter { + return componentCreationFailed +} + +// IncrementComponentCreationSucceeded increments the component creation succeeded metric. +func IncrementComponentCreationSucceeded(oldError, newError string) { + if oldError == "" || newError == "" || !strings.Contains(oldError, newError) { + // pair the componentCreationTotalReqs counter with componentCreationSucceeded because + // we dont want a situation where we increment componentCreationTotalReqs in the + // beginning of a reconcile, and we skip the componentCreationSucceeded metric because + // the errors are the same. Otherwise we will have a situation where neither the success + // nor the fail metric is increasing but the total request count is increasing. + componentCreationTotalReqs.Inc() + componentCreationSucceeded.Inc() + } +} + +func GetComponentCreationSucceeded() prometheus.Counter { + return componentCreationSucceeded +} + +func GetComponentCreationTotalReqs() prometheus.Counter { + return componentCreationTotalReqs +} diff --git a/pkg/metrics/component_test.go b/pkg/metrics/component_test.go new file mode 100644 index 000000000..e03c2c9c4 --- /dev/null +++ b/pkg/metrics/component_test.go @@ -0,0 +1,93 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 metrics + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" +) + +func TestComponentMetricsIncrement(t *testing.T) { + + tests := []struct { + name string + oldErr string + newErr string + expectSuccessIncremented bool + expectFailureIncremented bool + }{ + { + name: "no errors", + oldErr: "", + newErr: "", + expectSuccessIncremented: true, + expectFailureIncremented: false, + }, + { + name: "no old error, new error", + oldErr: "", + newErr: "error", + expectSuccessIncremented: true, + expectFailureIncremented: true, + }, + { + name: "old error, no new error", + oldErr: "error", + newErr: "", + expectSuccessIncremented: true, + expectFailureIncremented: false, + }, + { + name: "old error, new error - same error", + oldErr: "error", + newErr: "error", + expectSuccessIncremented: false, + expectFailureIncremented: false, + }, + { + name: "old error, new error - different error", + oldErr: "error", + newErr: "error 2", + expectSuccessIncremented: true, + expectFailureIncremented: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + beforeCreateSuccess := testutil.ToFloat64(componentCreationSucceeded) + beforeCreateFailed := testutil.ToFloat64(componentCreationFailed) + + IncrementComponentCreationSucceeded(tt.oldErr, tt.newErr) + + if tt.expectSuccessIncremented && testutil.ToFloat64(componentCreationSucceeded) <= beforeCreateSuccess { + t.Errorf("TestComponentMetricsIncrement error: expected component create success metrics to be incremented but was not incremented") + } else if !tt.expectSuccessIncremented && testutil.ToFloat64(componentCreationSucceeded) > beforeCreateSuccess { + t.Errorf("TestComponentMetricsIncrement error: expected component create success metrics not to be incremented but it was incremented") + } + + IncrementComponentCreationFailed(tt.oldErr, tt.newErr) + + if tt.expectFailureIncremented && testutil.ToFloat64(componentCreationFailed) <= beforeCreateFailed { + t.Errorf("TestComponentMetricsIncrement error: expected component create failed metrics to be incremented but was not incremented") + } else if !tt.expectFailureIncremented && testutil.ToFloat64(componentCreationFailed) > beforeCreateFailed { + t.Errorf("TestComponentMetricsIncrement error: expected component create failed metrics not to be incremented but it was incremented") + } + + }) + } +} diff --git a/pkg/metrics/git.go b/pkg/metrics/git.go new file mode 100644 index 000000000..143f5c190 --- /dev/null +++ b/pkg/metrics/git.go @@ -0,0 +1,75 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 metrics + +import "github.com/prometheus/client_golang/prometheus" + +var ( + ControllerGitRequest = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "controller_git_request", + Help: "Number of git operation requests. Not an SLI metric", + }, + []string{"controller", "tokenName", "operation"}, + ) + + SecondaryRateLimitCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "secondary_rate_limit_total", + Help: "Number of times the secondary rate limit has been reached. Not an SLI metric", + }, + []string{"controller", "tokenName", "operation"}, + ) + + PrimaryRateLimitCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "primary_rate_limit_total", + Help: "Number of times the primary rate limit has been reached. Not an SLI metric", + }, + []string{"controller", "tokenName", "operation"}, + ) + + TokenPoolGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "token_pool_gauge", + Help: "Gauge counter to track whether a token has been primary/secondary rate limited", + }, + + //rateLimited - can have the value of "primary" or "secondary" + //tokenName - the name of the token being rate limited + []string{"rateLimited", "tokenName"}, + ) + + ImportGitRepoTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_import_git_repo_total", + Help: "Number of import from git repository requests processed", + }, + ) + ImportGitRepoFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_failed_importc_git_repo_total", + Help: "Number of failed import from git repository requests", + }, + ) + + ImportGitRepoSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_successful_import_git_repo_total", + Help: "Number of successful import from git repository requests", + }, + ) +) diff --git a/pkg/metrics/gitops.go b/pkg/metrics/gitops.go new file mode 100644 index 000000000..3c6b5e729 --- /dev/null +++ b/pkg/metrics/gitops.go @@ -0,0 +1,40 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed 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 metrics + +import "github.com/prometheus/client_golang/prometheus" + +var ( + GitOpsRepoCreationTotalReqs = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_gitops_repo_creation_total", + Help: "Number of gitops creation requests processed", + }, + ) + GitOpsRepoCreationFailed = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_gitops_failed_repo_creation_total", + Help: "Number of failed gitops creation requests", + }, + ) + + GitOpsRepoCreationSucceeded = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "has_gitops_successful_repo_creation_total", + Help: "Number of successful gitops creation requests", + }, + ) +) diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 625dbbe63..e9cb85a30 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -21,170 +21,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics" ) -var ( - GitOpsRepoCreationTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_gitops_repo_creation_total", - Help: "Number of gitops creation requests processed", - }, - ) - GitOpsRepoCreationFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_gitops_failed_repo_creation_total", - Help: "Number of failed gitops creation requests", - }, - ) - - GitOpsRepoCreationSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_gitops_successful_repo_creation_total", - Help: "Number of successful gitops creation requests", - }, - ) - - ControllerGitRequest = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "controller_git_request", - Help: "Number of git operation requests. Not an SLI metric", - }, - []string{"controller", "tokenName", "operation"}, - ) - - SecondaryRateLimitCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "secondary_rate_limit_total", - Help: "Number of times the secondary rate limit has been reached. Not an SLI metric", - }, - []string{"controller", "tokenName", "operation"}, - ) - - PrimaryRateLimitCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "primary_rate_limit_total", - Help: "Number of times the primary rate limit has been reached. Not an SLI metric", - }, - []string{"controller", "tokenName", "operation"}, - ) - - TokenPoolGauge = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "token_pool_gauge", - Help: "Gauge counter to track whether a token has been primary/secondary rate limited", - }, - - //rateLimited - can have the value of "primary" or "secondary" - //tokenName - the name of the token being rate limited - []string{"rateLimited", "tokenName"}, - ) - - ApplicationDeletionTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_deletion_total", - Help: "Number of application deletion requests processed", - }, - ) - ApplicationDeletionFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_failed_deletion_total", - Help: "Number of failed application deletion requests", - }, - ) - - ApplicationDeletionSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_successful_deletion_total", - Help: "Number of successful application deletion requests", - }, - ) - - ApplicationCreationTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_creation_total", - Help: "Number of application creation requests processed", - }, - ) - ApplicationCreationFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_failed_creation_total", - Help: "Number of failed application creation requests", - }, - ) - - ApplicationCreationSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_application_successful_creation_total", - Help: "Number of successful application creation requests", - }, - ) - - ComponentCreationTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_creation_total", - Help: "Number of component creation requests processed", - }, - ) - ComponentCreationFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_failed_creation_total", - Help: "Number of failed component creation requests", - }, - ) - - ComponentCreationSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_successful_creation_total", - Help: "Number of successful component creation requests", - }, - ) - - ComponentDeletionTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_deletion_total", - Help: "Number of component deletion requests processed", - }, - ) - ComponentDeletionFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_failed_deletion_total", - Help: "Number of failed component deletion requests", - }, - ) - - ComponentDeletionSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_component_successful_deletion_total", - Help: "Number of successful component deletion requests", - }, - ) - - ImportGitRepoTotalReqs = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_import_git_repo_total", - Help: "Number of import from git repository requests processed", - }, - ) - ImportGitRepoFailed = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_failed_importc_git_repo_total", - Help: "Number of failed import from git repository requests", - }, - ) - - ImportGitRepoSucceeded = prometheus.NewCounter( - prometheus.CounterOpts{ - Name: "has_successful_import_git_repo_total", - Help: "Number of successful import from git repository requests", - }, - ) -) - func init() { // Register custom metrics with the global prometheus registry metrics.Registry.MustRegister(GitOpsRepoCreationTotalReqs, GitOpsRepoCreationFailed, GitOpsRepoCreationSucceeded, ControllerGitRequest, SecondaryRateLimitCounter, PrimaryRateLimitCounter, TokenPoolGauge, ApplicationDeletionTotalReqs, ApplicationDeletionSucceeded, ApplicationDeletionFailed, ApplicationCreationSucceeded, ApplicationCreationFailed, ApplicationCreationTotalReqs, - ComponentCreationTotalReqs, ComponentCreationSucceeded, ComponentCreationFailed, + componentCreationTotalReqs, componentCreationSucceeded, componentCreationFailed, ComponentDeletionTotalReqs, ComponentDeletionSucceeded, ComponentDeletionFailed, ImportGitRepoTotalReqs, ImportGitRepoFailed, ImportGitRepoSucceeded) }