Skip to content

Commit

Permalink
test: Enhance test coverage and fix controller implementation
Browse files Browse the repository at this point in the history
프로젝트 구조 개선 및 테스트 추가:
- Makefile 빌드 및 테스트 설정 개선
- API 타입 정의 및 생성된 DeepCopy 코드 추가
- GroupVersion 정보 수정
- Controller 로직 개선 및 Recorder 추가
- 테스트 커버리지 개선 (API: 82.4%, Controller: 73.1%)
  - API 타입 테스트 추가
  - Controller 테스트 케이스 확장
  - 알림 기능 테스트 추가
- Manager 설정 및 메트릭스 구성 수정
- Boilerplate 헤더 추가 (hack/)

Project structure improvements and test additions:
- Enhanced Makefile build and test configurations
- Added API type definitions and generated DeepCopy code
- Updated GroupVersion information
- Improved Controller logic and added Recorder
- Enhanced test coverage (API: 82.4%, Controller: 73.1%)
  - Added API type tests
  - Extended Controller test cases
  - Added notification functionality tests
- Updated Manager setup and metrics configuration
- Added boilerplate headers (hack/)

Signed-off-by: ddukbg <[email protected]>
  • Loading branch information
ddukbg committed Oct 24, 2024
1 parent 1e77d99 commit 1377b91
Show file tree
Hide file tree
Showing 10 changed files with 838 additions and 382 deletions.
58 changes: 40 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ endif
VERSION ?= $(shell git describe --tags --always --dirty)
IMG_TAG ?= $(VERSION)

# Tools 설정
CONTROLLER_GEN = $(GOBIN)/controller-gen
ENVTEST = $(GOBIN)/setup-envtest

.PHONY: all
all: build test
all: generate fmt vet build test

.PHONY: fmt
fmt:
Expand All @@ -27,13 +31,28 @@ vet:
go vet ./...

.PHONY: test
test: fmt vet
test: generate fmt vet
go test ./... -coverprofile cover.out

.PHONY: build
build:
build: generate
go build -o bin/manager main.go

# controller-gen 설치
.PHONY: controller-gen
controller-gen:
GOBIN=$(GOBIN) go install sigs.k8s.io/controller-tools/cmd/[email protected]

# Generate code and manifests
.PHONY: generate
generate: controller-gen
$(CONTROLLER_GEN) object paths="./api/v1alpha1/..." paths="./controllers/..."
$(CONTROLLER_GEN) crd paths="./api/v1alpha1/..." output:crd:artifacts:config=config/crd/bases

.PHONY: manifests
manifests: controller-gen
$(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=config/crd/bases

.PHONY: docker-build
docker-build:
docker build -t ${IMG}:${IMG_TAG} .
Expand All @@ -44,14 +63,14 @@ docker-push:

.PHONY: install
install:
kubectl apply -f config/crd/deployment_tracker.yaml
kubectl apply -f config/crd/bases/ddukbg.k8s_deploymenttrackers.yaml

.PHONY: uninstall
uninstall:
kubectl delete -f config/crd/deployment_tracker.yaml
kubectl delete -f config/crd/bases/ddukbg.k8s_deploymenttrackers.yaml

.PHONY: deploy
deploy: docker-build docker-push install
deploy: manifests docker-build docker-push install
kubectl apply -f config/rbac/
cat config/manager/manager.yaml | sed 's|IMAGE_TAG|${IMG_TAG}|g' | kubectl apply -f -

Expand All @@ -63,19 +82,9 @@ undeploy:

# 로컬 개발용 타겟 추가
.PHONY: run
run:
run: generate
go run ./main.go

# Generate code
.PHONY: generate
generate:
controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."

# Generate manifests
.PHONY: manifests
manifests:
controller-gen crd paths="./..." output:crd:artifacts:config=config/crd/bases

# 통합 테스트
.PHONY: integration-test
integration-test:
Expand All @@ -84,4 +93,17 @@ integration-test:
# 코드 커버리지 리포트
.PHONY: coverage
coverage:
go tool cover -html=cover.out
go tool cover -html=cover.out

# 로컬 테스트
.PHONY: local-test
local-test: generate fmt vet
go mod verify
go mod tidy
go test ./... -v
go build -v .

# GitHub Actions workflow 로컬 테스트용
.PHONY: test-workflow
test-workflow:
act -j test
55 changes: 30 additions & 25 deletions api/v1alpha1/deployment_tracker_types.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// api/v1alpha1/deployment_tracker_types.go
package v1alpha1

import (
Expand All @@ -6,37 +7,32 @@ import (

// DeploymentTrackerSpec defines the desired state of DeploymentTracker
type DeploymentTrackerSpec struct {
DeploymentName string `json:"deploymentName,omitempty"`
Namespace string `json:"namespace,omitempty"`
Notify Notify `json:"notify"`
DeploymentName string `json:"deploymentName,omitempty"`
Namespace string `json:"namespace,omitempty"`
Notify NotifyConfig `json:"notify"`
}

// Notify defines notification details (Slack or Email)
type Notify struct {
Slack string `json:"slack,omitempty"`
Email string `json:"email,omitempty"`
// NotifyConfig defines notification details
type NotifyConfig struct {
Slack string `json:"slack,omitempty"`
Email string `json:"email,omitempty"`
RetryCount int `json:"retryCount,omitempty"`
AlertOnFail bool `json:"alertOnFail,omitempty"`
}

// DeploymentTrackerStatus에 더 자세한 상태 정보 추가 필요
// DeploymentTrackerStatus defines the observed state of DeploymentTracker
type DeploymentTrackerStatus struct {
Ready bool `json:"ready,omitempty"`
// 추가할 필드들:
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
ObservedReplicas int32 `json:"observedReplicas,omitempty"`
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
Message string `json:"message,omitempty"`
Ready bool `json:"ready,omitempty"`
LastUpdated *metav1.Time `json:"lastUpdated,omitempty"`
ObservedReplicas int32 `json:"observedReplicas,omitempty"`
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
Message string `json:"message,omitempty"`
}

// Notify 구조체에 알림 설정 추가
type Notify struct {
Slack string `json:"slack,omitempty"`
Email string `json:"email,omitempty"`
// 추가할 필드들:
RetryCount int `json:"retryCount,omitempty"`
AlertOnFail bool `json:"alertOnFail,omitempty"`
}

// +kubebuilder:object:root=true
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready"
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=".metadata.creationTimestamp"

// DeploymentTracker is the Schema for the deploymenttrackers API
type DeploymentTracker struct {
Expand All @@ -47,7 +43,7 @@ type DeploymentTracker struct {
Status DeploymentTrackerStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
//+kubebuilder:object:root=true

// DeploymentTrackerList contains a list of DeploymentTracker
type DeploymentTrackerList struct {
Expand All @@ -59,3 +55,12 @@ type DeploymentTrackerList struct {
func init() {
SchemeBuilder.Register(&DeploymentTracker{}, &DeploymentTrackerList{})
}

// DeepCopyInto is required for the DeploymentTrackerStatus
func (in *DeploymentTrackerStatus) DeepCopyInto(out *DeploymentTrackerStatus) {
*out = *in
if in.LastUpdated != nil {
in, out := &in.LastUpdated, &out.LastUpdated
*out = (*in).DeepCopy()
}
}
117 changes: 117 additions & 0 deletions api/v1alpha1/deployment_tracker_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package v1alpha1

import (
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
"time"
)

func TestDeploymentTrackerTypes(t *testing.T) {
testTime := metav1.Time{Time: time.Now()}

tests := []struct {
name string
tracker *DeploymentTracker
}{
{
name: "기본 설정",
tracker: &DeploymentTracker{
ObjectMeta: metav1.ObjectMeta{
Name: "test-tracker",
Namespace: "default",
},
Spec: DeploymentTrackerSpec{
DeploymentName: "test-deployment",
Namespace: "default",
Notify: NotifyConfig{
Slack: "https://hooks.slack.com/test",
Email: "[email protected]",
},
},
Status: DeploymentTrackerStatus{
Ready: true,
LastUpdated: &testTime,
ObservedReplicas: 3,
ReadyReplicas: 3,
Message: "Deployment is ready",
},
},
},
{
name: "최소 설정",
tracker: &DeploymentTracker{
ObjectMeta: metav1.ObjectMeta{
Name: "minimal-tracker",
},
Spec: DeploymentTrackerSpec{
DeploymentName: "minimal-deployment",
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// DeepCopy 테스트
copied := tt.tracker.DeepCopy()
assert.Equal(t, tt.tracker.Name, copied.Name)
assert.Equal(t, tt.tracker.Namespace, copied.Namespace)
assert.Equal(t, tt.tracker.Spec, copied.Spec)
assert.Equal(t, tt.tracker.Status, copied.Status)

// DeepCopyObject 테스트
copiedObj := tt.tracker.DeepCopyObject()
copiedTracker, ok := copiedObj.(*DeploymentTracker)
assert.True(t, ok)
assert.Equal(t, tt.tracker.Name, copiedTracker.Name)

// List DeepCopy 테스트
list := &DeploymentTrackerList{
Items: []DeploymentTracker{*tt.tracker},
}
copiedList := list.DeepCopy()
assert.Equal(t, 1, len(copiedList.Items))
assert.Equal(t, tt.tracker.Name, copiedList.Items[0].Name)
})
}
}

func TestNotifyConfig(t *testing.T) {
tests := []struct {
name string
config NotifyConfig
valid bool
}{
{
name: "모든 알림 설정",
config: NotifyConfig{
Slack: "https://hooks.slack.com/test",
Email: "[email protected]",
RetryCount: 3,
AlertOnFail: true,
},
valid: true,
},
{
name: "Slack만 설정",
config: NotifyConfig{
Slack: "https://hooks.slack.com/test",
},
valid: true,
},
{
name: "Email만 설정",
config: NotifyConfig{
Email: "[email protected]",
},
valid: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.valid, len(tt.config.Slack) > 0 || len(tt.config.Email) > 0)
})
}
}
27 changes: 19 additions & 8 deletions api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
// api/v1alpha1/groupversion_info.go
package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

// GroupVersion is group version used to register these objects
var GroupVersion = scheme.GroupVersion{
Group: "ddukbg",
Version: "v1alpha1",
}
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{
Group: "ddukbg.k8s",
Version: "v1alpha1",
}

// SchemeBuilder adds the scheme to the manager
var SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

// Required for pkg/runtime.Object interface
var _ runtime.Object = &DeploymentTracker{}
var _ runtime.Object = &DeploymentTrackerList{}
Loading

0 comments on commit 1377b91

Please sign in to comment.