Skip to content

Commit

Permalink
Refactor determiner and add testcases (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
micnncim committed Sep 19, 2020
1 parent cd097da commit c281913
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 79 deletions.
4 changes: 2 additions & 2 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,11 @@ func (o *Options) Run(ctx context.Context, f cmdutil.Factory) error {
return nil // ignore resources in kube-system namespace
}

prune, err := o.determiner.DeterminePrune(ctx, info)
ok, err := o.determiner.DetermineDeletion(ctx, info)
if err != nil {
return err
}
if !prune {
if !ok {
return nil // skip deletion
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/determiner/determiner.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const (
kindHorizontalPodAutoscaler = "HorizontalPodAutoscaler"
)

// Determiner determines whether a resource should be pruned.
// Determiner determines whether a resource should be deleted.
type Determiner struct {
resourceClient resource.Client

Expand Down Expand Up @@ -103,8 +103,8 @@ func New(resourceClient resource.Client, r *cliresource.Result, namespace string
return d, nil
}

// DeterminePrune determines whether a resource should be pruned.
func (d *Determiner) DeterminePrune(ctx context.Context, info *cliresource.Info) (bool, error) {
// DetermineDeletion determines whether a resource should be deleted.
func (d *Determiner) DetermineDeletion(ctx context.Context, info *cliresource.Info) (bool, error) {
switch kind := info.Object.GetObjectKind().GroupVersionKind().Kind; kind {
case kindConfigMap:
if _, ok := d.UsedConfigMaps[info.Name]; !ok {
Expand Down
187 changes: 113 additions & 74 deletions pkg/determiner/determiner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
cliresource "k8s.io/cli-runtime/pkg/resource"
)

func Test_determiner_determinePrune(t *testing.T) {
func TestDeterminer_DetermineDeletion(t *testing.T) {
const (
fakeConfigMap = "fake-cm"
fakeSecret = "fake-secret"
fakePod = "fake-pod"
fakePersistentVolumeClaim = "fake-pvc"
fakePodDisruptionBudget = "fake-pdb"
fakeLabelKey1 = "fake-label1-key"
Expand All @@ -41,163 +42,201 @@ func Test_determiner_determinePrune(t *testing.T) {
wantErr bool
}{
{
name: "configmap should be pruned when it is used",
name: "ConfigMap should be deleted when it is not used",
args: args{
info: &cliresource.Info{
Name: fakeConfigMap,
Object: &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: kindConfigMap,
},
},
},
},
want: true,
wantErr: false,
},
{
name: "ConfigMap should not be deleted when it is used",
fields: fields{
usedConfigMaps: map[string]struct{}{
fakeConfigMap: {},
},
pods: []*corev1.Pod{
{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
EnvFrom: []corev1.EnvFromSource{
{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: fakeConfigMap,
},
},
},
},
},
},
},
},
},
},
args: args{
info: &cliresource.Info{
Name: fakeConfigMap,
Object: &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: kindConfigMap,
},
},
Name: fakeConfigMap,
},
},
want: false,
wantErr: false,
},
{
name: "configmap should not be pruned when it is not used",
name: "Secret should be deleted when it is not used",
args: args{
info: &cliresource.Info{
Object: &corev1.ConfigMap{
Name: fakeSecret,
Object: &corev1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: kindConfigMap,
Kind: kindSecret,
},
},
Name: fakeConfigMap,
},
},
want: true,
wantErr: false,
},
{
name: "secret should be pruned when it is used",
name: "Secret should not be deleted when it is used",
fields: fields{
usedSecrets: map[string]struct{}{
fakeSecret: {},
},
pods: []*corev1.Pod{
{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
EnvFrom: []corev1.EnvFromSource{
{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: fakeSecret,
},
},
},
},
},
},
},
args: args{
info: &cliresource.Info{
Name: fakeSecret,
Object: &corev1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: kindSecret,
},
},
},
},
want: false,
wantErr: false,
},
{
name: "Pod should be deleted when it is not running",
args: args{
info: &cliresource.Info{
Object: &corev1.Secret{
Name: fakePod,
Object: &corev1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: kindSecret,
Kind: kindPod,
},
Status: corev1.PodStatus{
Phase: corev1.PodFailed,
},
},
},
},
want: true,
wantErr: false,
},
{
name: "Pod should not be deleted when it is running",
args: args{
info: &cliresource.Info{
Name: fakePod,
Object: &corev1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: kindPod,
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
},
},
Name: fakeSecret,
},
},
want: false,
wantErr: false,
},
{
name: "secret should not be pruned when it is not used",
name: "PersistentVolumeClaim should be deleted when it is not used",
args: args{
info: &cliresource.Info{
Object: &corev1.Secret{
Name: fakePersistentVolumeClaim,
Object: &corev1.PersistentVolumeClaim{
TypeMeta: metav1.TypeMeta{
Kind: kindSecret,
Kind: kindPersistentVolumeClaim,
},
},
Name: fakeSecret,
},
},
want: true,
wantErr: false,
},
{
name: "pvc should be pruned when it is used",
name: "PersistentVolumeClaim should not be deleted when it is used",
fields: fields{
usedPersistentVolumes: map[string]struct{}{
fakePersistentVolumeClaim: {},
},
pods: []*corev1.Pod{
{
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
{
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: fakePersistentVolumeClaim,
},
},
},
},
},
},
},
},
args: args{
info: &cliresource.Info{
Object: &corev1.PersistentVolume{
Name: fakePersistentVolumeClaim,
Object: &corev1.PersistentVolumeClaim{
TypeMeta: metav1.TypeMeta{
Kind: kindPersistentVolumeClaim,
},
},
Name: fakePersistentVolumeClaim,
},
},
want: false,
wantErr: false,
},
{
name: "pvc should not be pruned when it is not used",
name: "PodDisruptionBudget should be deleted when it is not used",
args: args{
info: &cliresource.Info{
Object: &corev1.PersistentVolume{
Name: fakePodDisruptionBudget,
Object: &policyv1beta1.PodDisruptionBudget{
TypeMeta: metav1.TypeMeta{
Kind: kindPersistentVolumeClaim,
Kind: kindPodDisruptionBudget,
},
Spec: policyv1beta1.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
fakeLabelKey1: fakeLabelValue1,
},
},
},
},
Name: fakePersistentVolumeClaim,
},
},
want: true,
wantErr: false,
},
{
name: "PodDisruptionBudget should not be deleted when it is used",
fields: fields{
pods: []*corev1.Pod{
{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
fakeLabelKey1: fakeLabelValue1,
},
},
},
},
},
args: args{
info: &cliresource.Info{
Name: fakePodDisruptionBudget,
Object: &policyv1beta1.PodDisruptionBudget{
TypeMeta: metav1.TypeMeta{
Kind: kindPodDisruptionBudget,
},
Spec: policyv1beta1.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
fakeLabelKey1: fakeLabelValue1,
},
},
},
},
},
},
want: false,
wantErr: false,
},
}

for _, tt := range tests {
Expand All @@ -213,7 +252,7 @@ func Test_determiner_determinePrune(t *testing.T) {
Pods: tt.fields.pods,
}

got, err := d.DeterminePrune(context.Background(), tt.args.info)
got, err := d.DetermineDeletion(context.Background(), tt.args.info)
if (err != nil) != tt.wantErr {
t.Errorf("determiner.determinePrune() error = %v, wantErr %v", err, tt.wantErr)
return
Expand All @@ -225,7 +264,7 @@ func Test_determiner_determinePrune(t *testing.T) {
}
}

func Test_determineUsedPodDisruptionBudget(t *testing.T) {
func TestDeterminer_determineUsedPodDisruptionBudget(t *testing.T) {
const (
fakePodDisruptionBudget = "fake-pdb"
fakePod1 = "fake-pod1"
Expand Down

0 comments on commit c281913

Please sign in to comment.