Skip to content

Commit

Permalink
Unit Tests for podchaos (chaos-mesh#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
oraluben authored Mar 16, 2020
1 parent 416be27 commit 3d40e16
Show file tree
Hide file tree
Showing 16 changed files with 474 additions and 93 deletions.
2 changes: 1 addition & 1 deletion controllers/iochaos/fs/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, chaos reconcil

pods, err := utils.SelectAndFilterPods(ctx, r.Client, &iochaos.Spec)
if err != nil {
r.Log.Error(err, "failed to select and generate pods")
r.Log.Error(err, "failed to select and filter pods")
return err
}

Expand Down
2 changes: 1 addition & 1 deletion controllers/kernelchaos/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, chaos reconcil
pods, err := utils.SelectAndFilterPods(ctx, r.Client, &kernelchaos.Spec)

if err != nil {
r.Log.Error(err, "failed to select and generate pods")
r.Log.Error(err, "failed to select and filter pods")
return err
}

Expand Down
2 changes: 1 addition & 1 deletion controllers/networkchaos/netem/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, chaos reconcil
pods, err := utils.SelectAndFilterPods(ctx, r.Client, &networkchaos.Spec)

if err != nil {
r.Log.Error(err, "failed to select and generate pods")
r.Log.Error(err, "failed to select and filter pods")
return err
}

Expand Down
4 changes: 2 additions & 2 deletions controllers/networkchaos/partition/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, chaos reconcil
sources, err := utils.SelectAndFilterPods(ctx, r.Client, &networkchaos.Spec)

if err != nil {
r.Log.Error(err, "failed to select and generate pods")
r.Log.Error(err, "failed to select and filter pods")
return err
}

targets, err := utils.SelectAndFilterPods(ctx, r.Client, &networkchaos.Spec.Target)

if err != nil {
r.Log.Error(err, "failed to select and generate pods")
r.Log.Error(err, "failed to select and filter pods")
return err
}

Expand Down
97 changes: 97 additions & 0 deletions controllers/podchaos/containerkill/containerkill_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package containerkill_test

import (
"context"
"errors"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/pingcap/chaos-mesh/api/v1alpha1"
controllerkill "github.com/pingcap/chaos-mesh/controllers/podchaos/containerkill"
. "github.com/pingcap/chaos-mesh/controllers/test"
"github.com/pingcap/chaos-mesh/pkg/mock"
)

func TestContainerKill(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecsWithDefaultAndCustomReporters(t,
"ContainerKill Suite",
[]Reporter{envtest.NewlineReporter{}})
}

var _ = BeforeSuite(func(done Done) {
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))

Expect(v1.AddToScheme(scheme.Scheme)).To(Succeed())
Expect(v1alpha1.AddToScheme(scheme.Scheme)).To(Succeed())

close(done)
}, 60)

var _ = AfterSuite(func() {
})

var _ = Describe("PodChaos", func() {
Context("ContainerKill", func() {
objs, _ := GenerateNPods("p", 1, v1.PodRunning, metav1.NamespaceDefault, nil, nil, v1.ContainerStatus{
ContainerID: "fake-container-id",
Name: "container-name",
})

podChaos := v1alpha1.PodChaos{
TypeMeta: metav1.TypeMeta{
Kind: "PodChaos",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault,
Name: "podchaos-name",
},
Spec: v1alpha1.PodChaosSpec{
Selector: v1alpha1.SelectorSpec{},
Mode: v1alpha1.OnePodMode,
ContainerName: "container-name",
Scheduler: &v1alpha1.SchedulerSpec{Cron: "@hourly"},
},
}

r := controllerkill.Reconciler{
Client: fake.NewFakeClientWithScheme(scheme.Scheme, objs...),
EventRecorder: &record.FakeRecorder{},
Log: ctrl.Log.WithName("controllers").WithName("PodChaos"),
}

It("ContainerKill Apply", func() {
defer mock.With("MockChaosDaemonClient", &MockChaosDaemonClient{})()

err := r.Apply(context.TODO(), ctrl.Request{}, &podChaos)
Expect(err).ToNot(HaveOccurred())

err = r.Recover(context.TODO(), ctrl.Request{}, &podChaos)
Expect(err).ToNot(HaveOccurred())
})

It("ContainerKill Apply Error", func() {
defer mock.With("MockChaosDaemonClient", &MockChaosDaemonClient{})()
defer mock.With("MockContainerKillError", errors.New("ContainerKillError"))()

err := r.Apply(context.TODO(), ctrl.Request{}, &podChaos)

Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("ContainerKillError"))
})
})
})
42 changes: 17 additions & 25 deletions controllers/podchaos/containerkill/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package containerkill

import (
"context"
"errors"
"fmt"
"os"
"time"
Expand Down Expand Up @@ -65,11 +66,10 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, obj reconciler
var err error
now := time.Now()

r.Log.Info("Reconciling container kill")

var podchaos v1alpha1.PodChaos
if err = r.Get(ctx, req.NamespacedName, &podchaos); err != nil {
r.Log.Error(err, "unable to get podchaos")
podchaos, ok := obj.(*v1alpha1.PodChaos)
if !ok {
err = errors.New("chaos is not PodChaos")
r.Log.Error(err, "chaos is not PodChaos", "chaos", obj)
return err
}

Expand All @@ -78,26 +78,15 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, obj reconciler
return fmt.Errorf("podchaos[%s/%s] the name of container is empty", podchaos.Namespace, podchaos.Name)
}

pods, err := utils.SelectPods(ctx, r.Client, podchaos.Spec.Selector)
if err != nil {
r.Log.Error(err, "fail to get selected pods")
return err
}

if len(pods) == 0 {
r.Log.Error(nil, "no pod is selected", "name", req.Name, "namespace", req.Namespace)
return fmt.Errorf("podchaos[%s/%s] no pod is selected", podchaos.Namespace, podchaos.Name)
}

filteredPod, err := utils.FilterPodsByMode(pods, podchaos.Spec.Mode, podchaos.Spec.Value)
pods, err := utils.SelectAndFilterPods(ctx, r.Client, &podchaos.Spec)
if err != nil {
r.Log.Error(err, "fail to generate pods")
r.Log.Error(err, "fail to select and filter pods")
return err
}

g := errgroup.Group{}
for podIndex := range filteredPod {
pod := &filteredPod[podIndex]
for podIndex := range pods {
pod := &pods[podIndex]
haveContainer := false

for containerIndex := range pod.Status.ContainerStatuses {
Expand All @@ -106,10 +95,13 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, obj reconciler

if containerName == podchaos.Spec.ContainerName {
haveContainer = true
err = r.KillContainer(ctx, pod, containerID)
if err != nil {
r.Log.Error(err, "failed to kill container")
}
g.Go(func() error {
err = r.KillContainer(ctx, pod, containerID)
if err != nil {
r.Log.Error(err, "failed to kill container")
}
return err
})
}
}

Expand All @@ -121,7 +113,7 @@ func (r *Reconciler) Apply(ctx context.Context, req ctrl.Request, obj reconciler
if err := g.Wait(); err != nil {
return err
}
if err = r.updatePodchaos(ctx, podchaos, pods, now); err != nil {
if err = r.updatePodchaos(ctx, *podchaos, pods, now); err != nil {
return err
}
r.Event(obj, v1.EventTypeNormal, utils.EventChaosInjected, "")
Expand Down
89 changes: 89 additions & 0 deletions controllers/podchaos/podchaos_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package podchaos_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/pingcap/chaos-mesh/api/v1alpha1"
"github.com/pingcap/chaos-mesh/controllers/podchaos"
)

func TestPodChaos(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecsWithDefaultAndCustomReporters(t,
"PodChaos Suite",
[]Reporter{envtest.NewlineReporter{}})
}

var _ = BeforeSuite(func(done Done) {
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
close(done)
}, 60)

var _ = AfterSuite(func() {
})

var _ = Describe("PodChaos", func() {
Context("PodChaos", func() {
invalidDuration := "invalid duration"
meta := metav1.TypeMeta{
Kind: "PodChaos",
APIVersion: "v1",
}

r := podchaos.Reconciler{
Client: fake.NewFakeClientWithScheme(scheme.Scheme),
EventRecorder: &record.FakeRecorder{},
Log: ctrl.Log.WithName("controllers").WithName("PodChaos"),
}

It("PodChaos Reconcile", func() {
var err error

_, err = r.Reconcile(ctrl.Request{}, &v1alpha1.PodChaos{
TypeMeta: meta,
Spec: v1alpha1.PodChaosSpec{Scheduler: nil, Duration: &invalidDuration},
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid duration"))

_, err = r.Reconcile(ctrl.Request{}, &v1alpha1.PodChaos{
TypeMeta: meta,
Spec: v1alpha1.PodChaosSpec{Scheduler: nil, Duration: nil, Action: v1alpha1.PodKillAction},
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("unsupported chaos action"))
_, err = r.Reconcile(ctrl.Request{}, &v1alpha1.PodChaos{
TypeMeta: meta,
Spec: v1alpha1.PodChaosSpec{Scheduler: nil, Duration: nil, Action: v1alpha1.ContainerKillAction},
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("unsupported chaos action"))
_, err = r.Reconcile(ctrl.Request{}, &v1alpha1.PodChaos{
TypeMeta: meta,
Spec: v1alpha1.PodChaosSpec{Scheduler: nil, Duration: nil, Action: ""},
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid chaos action"))

_, err = r.Reconcile(ctrl.Request{}, &v1alpha1.PodChaos{
TypeMeta: meta,
Spec: v1alpha1.PodChaosSpec{Scheduler: &v1alpha1.SchedulerSpec{}, Duration: nil, Action: ""},
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid chaos action"))
})
})
})
Loading

0 comments on commit 3d40e16

Please sign in to comment.