Skip to content

Commit

Permalink
Refactor GitHub mock server (#1023)
Browse files Browse the repository at this point in the history
* Refactor GitHub mock server

* Isolate endpoints

* Refactor

* Extract Endpoints

* Renumber
  • Loading branch information
int128 authored Jan 7, 2024
1 parent 6753940 commit 3e0c4ec
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 214 deletions.
30 changes: 23 additions & 7 deletions internal/controller/applicationhealthcomment_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package controller

import (
"context"
"net/http"
"time"

argocdv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/int128/argocd-commenter/internal/controller/githubmock"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -27,7 +29,7 @@ var _ = Describe("Application health comment controller", func() {
Spec: argocdv1alpha1.ApplicationSpec{
Project: "default",
Source: &argocdv1alpha1.ApplicationSource{
RepoURL: "https://github.com/int128/manifests.git",
RepoURL: "https://github.com/test/health-comment.git",
Path: "test",
TargetRevision: "main",
},
Expand All @@ -42,6 +44,13 @@ var _ = Describe("Application health comment controller", func() {

Context("When an application is healthy", func() {
It("Should notify a comment once", func(ctx context.Context) {
var comment githubmock.Comment
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/health-comment/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101/pulls": githubmock.ListPullRequestsWithCommit(101),
"GET /api/v3/repos/test/health-comment/pulls/101/files": githubmock.ListFiles(),
"POST /api/v3/repos/test/health-comment/issues/101/comments": comment.CreateEndpoint(),
})

By("Updating the application to progressing")
app.Status = argocdv1alpha1.ApplicationStatus{
Health: argocdv1alpha1.HealthStatus{
Expand All @@ -51,7 +60,7 @@ var _ = Describe("Application health comment controller", func() {
StartedAt: metav1.Now(),
Operation: argocdv1alpha1.Operation{
Sync: &argocdv1alpha1.SyncOperation{
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200",
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101",
},
},
},
Expand All @@ -61,7 +70,7 @@ var _ = Describe("Application health comment controller", func() {
By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(200) }).Should(Equal(1))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(1))

By("Updating the application to progressing")
app.Status.Health.Status = health.HealthStatusProgressing
Expand All @@ -70,12 +79,19 @@ var _ = Describe("Application health comment controller", func() {
By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Consistently(func() int { return githubMock.Comments.CountBy(200) }, 100*time.Millisecond).Should(Equal(1))
Consistently(func() int { return comment.CreateCount() }, 100*time.Millisecond).Should(Equal(1))
}, SpecTimeout(3*time.Second))
})

Context("When an application is degraded and then healthy", func() {
It("Should notify a comment for degraded and healthy", func(ctx context.Context) {
var comment githubmock.Comment
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/health-comment/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102/pulls": githubmock.ListPullRequestsWithCommit(102),
"GET /api/v3/repos/test/health-comment/pulls/102/files": githubmock.ListFiles(),
"POST /api/v3/repos/test/health-comment/issues/102/comments": comment.CreateEndpoint(),
})

By("Updating the application to progressing")
app.Status = argocdv1alpha1.ApplicationStatus{
Health: argocdv1alpha1.HealthStatus{
Expand All @@ -85,7 +101,7 @@ var _ = Describe("Application health comment controller", func() {
StartedAt: metav1.Now(),
Operation: argocdv1alpha1.Operation{
Sync: &argocdv1alpha1.SyncOperation{
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201",
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102",
},
},
},
Expand All @@ -95,12 +111,12 @@ var _ = Describe("Application health comment controller", func() {
By("Updating the application to degraded")
app.Status.Health.Status = health.HealthStatusDegraded
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(201) }).Should(Equal(1))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(1))

By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(201) }).Should(Equal(2))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(2))
}, SpecTimeout(3*time.Second))
})
})
63 changes: 38 additions & 25 deletions internal/controller/applicationhealthdeployment_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package controller

import (
"context"
"net/http"
"time"

argocdv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/google/go-github/v57/github"
"github.com/int128/argocd-commenter/internal/controller/githubmock"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
Expand All @@ -30,7 +31,7 @@ var _ = Describe("Application health deployment controller", func() {
Spec: argocdv1alpha1.ApplicationSpec{
Project: "default",
Source: &argocdv1alpha1.ApplicationSource{
RepoURL: "https://github.com/int128/manifests.git",
RepoURL: "https://github.com/test/health-deployment.git",
Path: "test",
TargetRevision: "main",
},
Expand Down Expand Up @@ -60,23 +61,27 @@ var _ = Describe("Application health deployment controller", func() {

Context("When an application is healthy", func() {
It("Should notify a deployment status once", func(ctx context.Context) {
githubMock.DeploymentStatuses.SetResponse(999300, []*github.DeploymentStatus{})
var deploymentStatus githubmock.DeploymentStatus
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/health-deployment/deployments/101/statuses": deploymentStatus.ListEndpoint(),
"POST /api/v3/repos/test/health-deployment/deployments/101/statuses": deploymentStatus.CreateEndpoint(),
})

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999300",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/101",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())

By("Updating the application to degraded")
app.Status.Health.Status = health.HealthStatusDegraded
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.DeploymentStatuses.CountBy(999300) }).Should(Equal(1))
Eventually(func() int { return deploymentStatus.CreateCount() }).Should(Equal(1))

By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.DeploymentStatuses.CountBy(999300) }).Should(Equal(2))
Eventually(func() int { return deploymentStatus.CreateCount() }).Should(Equal(2))

By("Updating the application to progressing")
app.Status.Health.Status = health.HealthStatusProgressing
Expand All @@ -85,17 +90,21 @@ var _ = Describe("Application health deployment controller", func() {
By("Updating the application to healthy, again")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Consistently(func() int { return githubMock.DeploymentStatuses.CountBy(999300) }, "100ms").Should(Equal(2))
Consistently(func() int { return deploymentStatus.CreateCount() }, "100ms").Should(Equal(2))
}, SpecTimeout(3*time.Second))
})

Context("When the deployment annotation is updated and then the application becomes healthy", func() {
It("Should notify a deployment status", func(ctx context.Context) {
githubMock.DeploymentStatuses.SetResponse(999301, []*github.DeploymentStatus{})
var deploymentStatus githubmock.DeploymentStatus
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/health-deployment/deployments/102/statuses": deploymentStatus.ListEndpoint(),
"POST /api/v3/repos/test/health-deployment/deployments/102/statuses": deploymentStatus.CreateEndpoint(),
})

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999999",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/999",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())

Expand All @@ -105,10 +114,10 @@ var _ = Describe("Application health deployment controller", func() {

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999301",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/102",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Consistently(func() int { return githubMock.DeploymentStatuses.CountBy(999301) }, "100ms").Should(BeZero())
Consistently(func() int { return deploymentStatus.CreateCount() }, "100ms").Should(BeZero())

By("Updating the application to progressing")
app.Status.Health.Status = health.HealthStatusProgressing
Expand All @@ -117,36 +126,40 @@ var _ = Describe("Application health deployment controller", func() {
By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.DeploymentStatuses.CountBy(999301) }).Should(Equal(1))
Eventually(func() int { return deploymentStatus.CreateCount() }).Should(Equal(1))
}, SpecTimeout(3*time.Second))
})

Context("When an application became healthy before the deployment annotation is updated", func() {
It("Should notify a deployment status when the deployment annotation is valid", func(ctx context.Context) {
githubMock.DeploymentStatuses.SetResponse(999302, []*github.DeploymentStatus{})
var deploymentStatusOld, deploymentStatusNew githubmock.DeploymentStatus
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/health-deployment/deployments/103/statuses": deploymentStatusOld.ListEndpoint(),
"POST /api/v3/repos/test/health-deployment/deployments/103/statuses": deploymentStatusOld.CreateEndpoint(),
"GET /api/v3/repos/test/health-deployment/deployments/104/statuses": deploymentStatusNew.ListEndpoint(),
"POST /api/v3/repos/test/health-deployment/deployments/104/statuses": deploymentStatusNew.CreateEndpoint(),
})

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999999",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/999",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())

By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Consistently(func() int { return githubMock.DeploymentStatuses.CountBy(999302) }, "100ms").Should(BeZero())
Consistently(func() int { return deploymentStatusOld.CreateCount() }, "100ms").Should(BeZero())

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999302",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/103",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.DeploymentStatuses.CountBy(999302) }).Should(Equal(1))
Eventually(func() int { return deploymentStatusOld.CreateCount() }).Should(Equal(1))

By("Deleting the old deployment")
githubMock.DeploymentStatuses.SetResponse(999302, nil)
By("Creating a new deployment")
githubMock.DeploymentStatuses.SetResponse(999303, []*github.DeploymentStatus{})
deploymentStatusOld.NotFound = true

By("Updating the application to progressing")
app.Status.Health.Status = health.HealthStatusProgressing
Expand All @@ -155,21 +168,21 @@ var _ = Describe("Application health deployment controller", func() {
By("Updating the application to healthy")
app.Status.Health.Status = health.HealthStatusHealthy
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Consistently(func() int { return githubMock.DeploymentStatuses.CountBy(999303) }, "100ms").Should(BeZero())
Consistently(func() int { return deploymentStatusNew.CreateCount() }, "100ms").Should(BeZero())

By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999303",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/104",
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.DeploymentStatuses.CountBy(999303) }).Should(Equal(1))
Expect(githubMock.DeploymentStatuses.CountBy(999302)).Should(Equal(1))
Eventually(func() int { return deploymentStatusNew.CreateCount() }).Should(Equal(1))
Expect(deploymentStatusOld.CreateCount()).Should(Equal(1))
}, SpecTimeout(3*time.Second))

It("Should retry a deployment status until timeout", func(ctx context.Context) {
By("Updating the deployment annotation")
app.Annotations = map[string]string{
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/int128/manifests/deployments/999999",
"argocd-commenter.int128.github.io/deployment-url": "https://api.github.com/repos/test/health-deployment/deployments/999",
}
app.Status = argocdv1alpha1.ApplicationStatus{
OperationState: &argocdv1alpha1.OperationState{
Expand Down
30 changes: 23 additions & 7 deletions internal/controller/applicationphasecomment_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package controller

import (
"context"
"net/http"
"time"

argocdv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/int128/argocd-commenter/internal/controller/githubmock"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -27,7 +29,7 @@ var _ = Describe("Application phase controller", func() {
Spec: argocdv1alpha1.ApplicationSpec{
Project: "default",
Source: &argocdv1alpha1.ApplicationSource{
RepoURL: "https://github.com/int128/manifests.git",
RepoURL: "https://github.com/test/phase-comment.git",
Path: "test",
TargetRevision: "main",
},
Expand All @@ -42,49 +44,63 @@ var _ = Describe("Application phase controller", func() {

Context("When an application is synced", func() {
It("Should notify a comment", func(ctx context.Context) {
var comment githubmock.Comment
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/phase-comment/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101/pulls": githubmock.ListPullRequestsWithCommit(101),
"GET /api/v3/repos/test/phase-comment/pulls/101/files": githubmock.ListFiles(),
"POST /api/v3/repos/test/phase-comment/issues/101/comments": comment.CreateEndpoint(),
})

By("Updating the application to running")
app.Status = argocdv1alpha1.ApplicationStatus{
OperationState: &argocdv1alpha1.OperationState{
Phase: synccommon.OperationRunning,
StartedAt: metav1.Now(),
Operation: argocdv1alpha1.Operation{
Sync: &argocdv1alpha1.SyncOperation{
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100",
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101",
},
},
},
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(100) }).Should(Equal(1))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(1))

By("Updating the application to succeeded")
app.Status.OperationState.Phase = synccommon.OperationSucceeded
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(100) }).Should(Equal(2))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(2))
}, SpecTimeout(3*time.Second))
})

Context("When an application sync operation is failed", func() {
It("Should notify a comment", func(ctx context.Context) {
var comment githubmock.Comment
githubServer.AddHandlers(map[string]http.Handler{
"GET /api/v3/repos/test/phase-comment/commits/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102/pulls": githubmock.ListPullRequestsWithCommit(102),
"GET /api/v3/repos/test/phase-comment/pulls/102/files": githubmock.ListFiles(),
"POST /api/v3/repos/test/phase-comment/issues/102/comments": comment.CreateEndpoint(),
})

By("Updating the application to running")
app.Status = argocdv1alpha1.ApplicationStatus{
OperationState: &argocdv1alpha1.OperationState{
Phase: synccommon.OperationRunning,
StartedAt: metav1.Now(),
Operation: argocdv1alpha1.Operation{
Sync: &argocdv1alpha1.SyncOperation{
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101",
Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102",
},
},
},
}
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(101) }).Should(Equal(1))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(1))

By("Updating the application to failed")
app.Status.OperationState.Phase = synccommon.OperationFailed
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
Eventually(func() int { return githubMock.Comments.CountBy(101) }).Should(Equal(2))
Eventually(func() int { return comment.CreateCount() }).Should(Equal(2))
}, SpecTimeout(3*time.Second))
})
})
Loading

0 comments on commit 3e0c4ec

Please sign in to comment.