aboutsummaryrefslogtreecommitdiffstats
path: root/vnfs/DAaaS/microservices/collectd-operator
diff options
context:
space:
mode:
Diffstat (limited to 'vnfs/DAaaS/microservices/collectd-operator')
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/Makefile2
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/go.mod1
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/go.sum1
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go13
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go13
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go13
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller_test.go536
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go15
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller_test.go370
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go13
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go13
-rw-r--r--vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/predicate.go25
12 files changed, 1000 insertions, 15 deletions
diff --git a/vnfs/DAaaS/microservices/collectd-operator/Makefile b/vnfs/DAaaS/microservices/collectd-operator/Makefile
index c09f4c24..9c023521 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/Makefile
+++ b/vnfs/DAaaS/microservices/collectd-operator/Makefile
@@ -47,7 +47,7 @@ debug:
@go build -o ${COP_LOCAL} collectd-operator/cmd/manager
## deploy: Build Dockerfile and publish to repository
-deploy: build publish
+deploy: build test publish
## publish: Push docker image to repository
publish:
diff --git a/vnfs/DAaaS/microservices/collectd-operator/go.mod b/vnfs/DAaaS/microservices/collectd-operator/go.mod
index 525d4e3f..fefba3d5 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/go.mod
+++ b/vnfs/DAaaS/microservices/collectd-operator/go.mod
@@ -6,6 +6,7 @@ require (
github.com/go-openapi/spec v0.19.0
github.com/operator-framework/operator-sdk v0.9.1-0.20190807211748-fe8c81ad98c0
github.com/spf13/pflag v1.0.3
+ github.com/stretchr/testify v1.3.0
k8s.io/api v0.0.0-20190612125737-db0771252981
k8s.io/apimachinery v0.0.0-20190612125636-6a5db36e93ad
k8s.io/client-go v11.0.0+incompatible
diff --git a/vnfs/DAaaS/microservices/collectd-operator/go.sum b/vnfs/DAaaS/microservices/collectd-operator/go.sum
index b5b3019c..4a53436e 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/go.sum
+++ b/vnfs/DAaaS/microservices/collectd-operator/go.sum
@@ -83,6 +83,7 @@ github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ=
github.com/evanphx/json-patch v3.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc=
github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go
index d5c69fbd..f14294e2 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 v1alpha1
import (
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go
index eb338639..d814592b 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 v1alpha1
import (
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go
index 8c6023b8..d1bd5c6a 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 collectdglobal
import (
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller_test.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller_test.go
new file mode 100644
index 00000000..2410fe6a
--- /dev/null
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller_test.go
@@ -0,0 +1,536 @@
+/*
+Copyright 2019 Intel Corporation.
+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 collectdglobal
+
+import (
+ "context"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+
+ onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
+ utils "collectd-operator/pkg/controller/utils"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/util/intstr"
+ "k8s.io/client-go/kubernetes/scheme"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+)
+
+const (
+ name = "collectd-operator"
+ namespace = "test1"
+ gOpts = "BaseDir \"/opt/collectd/var/lib/collectd\"\nPIDFile \"/opt/collectd/var/run/collectd.pid\"\nPluginDir" +
+ "\"/opt/collectd/lib/collectd\"\nTypesDB \"/opt/collectd/share/collectd/types.db\"\n" +
+ "#Hostname \"localhost\"\nInterval 1 \nWriteQueueLimitHigh" +
+ "10000000\nWriteQueueLimitLow 8000000\nTimeout \"10\"\nReadThreads \"50\"\nWriteThreads" +
+ "\"50\"\n\n#Enable plugins:\n\nLoadPlugin cpufreq\nLoadPlugin ipmi\nLoadPlugin" +
+ "turbostat\nLoadPlugin irq\nLoadPlugin memcached\nLoadPlugin memory\nLoadPlugin" +
+ "processes\nLoadPlugin load\n"
+ typesCmName = "types-configmap"
+ watchLabels = "app=collectd"
+)
+
+var (
+ one = intstr.FromInt(1)
+ ls, _ = labels.ConvertSelectorToLabelsMap(watchLabels)
+ cm = &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cp-config-map",
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Data: map[string]string{
+ "collectd.conf": "",
+ },
+ }
+ typesCm = &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: typesCmName,
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Data: map[string]string{
+ "types.db": "types.db data",
+ },
+ }
+ ds = &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cp-collectd",
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Spec: appsv1.DaemonSetSpec{
+ Selector: &metav1.LabelSelector{MatchLabels: ls},
+ UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
+ Type: appsv1.RollingUpdateDaemonSetStrategyType,
+ RollingUpdate: &appsv1.RollingUpdateDaemonSet{
+ MaxUnavailable: &one,
+ },
+ },
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: ls,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{{Name: "foo", Image: "bar"}},
+ },
+ },
+ },
+ }
+
+ cp = &onapv1alpha1.CollectdPlugin{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cpu",
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdPluginSpec{
+ PluginName: "cpu",
+ PluginConf: "Interval 10",
+ },
+ }
+
+ cpList = &onapv1alpha1.CollectdPluginList{
+ Items: []onapv1alpha1.CollectdPlugin{},
+ }
+)
+
+// TestCollectdGlobalController runs ReconcileCollectdGlobal.Reconcile() against a
+// fake client that tracks a CollectdGlobal object.
+
+// Reconcile No CR exist.
+func TestCollectdGlobalNoCR(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ cg := &onapv1alpha1.CollectdGlobal{}
+
+ cgList := &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{},
+ }
+
+ _ = cp
+
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ cm,
+ ds,
+ cgList,
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cg, cgList, cpList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ res, err := rcg.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ // Check the result of reconciliation to make sure it has the desired state.
+ if res.Requeue {
+ t.Error("Unexpected Reconcile requeue request")
+ }
+}
+
+// Test CollectdGlobalController - Add CR with non existent ConfigMap.
+func TestCollectdGlobalNoCM(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ cg := &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ }
+
+ cgList := &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{*cg},
+ }
+
+ _ = cp
+
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ ds,
+ cgList,
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cg, cgList, cpList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ defer func() {
+ if r := recover(); r == nil {
+ t.Errorf("The code did not panic")
+ } else {
+ t.Log("Successful Panic")
+ }
+ }()
+ res, err := rcg.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ // Check the result of reconciliation to make sure it has the desired state.
+ if !res.Requeue {
+ t.Error("Reconcile did not requeue request as expected")
+ }
+}
+
+// Test CollectdGlobalController - HandleDelete
+func TestCollectdGlobalHandleDelete(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ cg := &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ DeletionTimestamp: &metav1.Time{
+ Time: time.Now(),
+ },
+ Finalizers: []string{
+ utils.CollectdFinalizer,
+ },
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ }
+
+ cgList := &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{*cg},
+ }
+
+ _ = cp
+
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ cm,
+ ds,
+ cgList,
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cg, cgList, cpList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ res, err := rcg.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ // Check the result of reconciliation to make sure it has the desired state.
+ if res.Requeue {
+ t.Error("Unexpected Reconcile requeue request")
+ }
+}
+
+// Test CollectdGlobalController
+func TestCollectdGlobalController(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ cg := &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ }
+
+ cgList := &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{*cg},
+ }
+
+ _ = cp
+
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ cm,
+ ds,
+ cgList,
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cg, cgList, cpList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ res, err := rcg.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ // Check the result of reconciliation to make sure it has the desired state.
+ if res.Requeue {
+ t.Error("Unexpected Reconcile requeue request")
+ }
+}
+
+// Test HandleTypesDB
+func TestHandleTypesDB(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ cg := &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ ConfigMap: typesCmName,
+ },
+ }
+
+ cgList := &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{*cg},
+ }
+
+ _ = cp
+
+ testCases := []struct {
+ name string
+ createTypesCm bool
+ }{
+ {name: "Handle TypesDB missing TypesDB ConfigMap", createTypesCm: false},
+ {name: "Handle TypesDB", createTypesCm: true},
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ cm,
+ ds,
+ cgList,
+ }
+ if testCase.createTypesCm {
+ objs = append(objs, typesCm)
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cg, cgList, cpList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ res, err := rcg.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ // Check the result of reconciliation to make sure it has the desired state.
+ if res.Requeue {
+ t.Error("Unexpected Reconcile requeue request")
+ }
+ })
+ }
+}
+
+// Test UpdateStatus
+func TestUpdateStatus(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ testCases := []struct {
+ name string
+ cg *onapv1alpha1.CollectdGlobal
+ createPods bool
+ expectedStatus string
+ expectedError error
+ }{
+ {
+ name: "Update Status of New CR",
+ cg: &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ },
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Initial state to Created",
+ cg: &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ Status: onapv1alpha1.CollectdGlobalStatus{
+ Status: onapv1alpha1.Initial,
+ },
+ },
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Created state - No Pods",
+ cg: &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ Status: onapv1alpha1.CollectdGlobalStatus{
+ Status: onapv1alpha1.Created,
+ },
+ },
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Created state to Enabled",
+ cg: &onapv1alpha1.CollectdGlobal{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdGlobalSpec{
+ GlobalOptions: gOpts,
+ },
+ Status: onapv1alpha1.CollectdGlobalStatus{
+ Status: onapv1alpha1.Created,
+ },
+ },
+ createPods: true,
+ expectedStatus: onapv1alpha1.Enabled,
+ expectedError: nil,
+ },
+ }
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ testCase.cg,
+ }
+ if testCase.createPods {
+ pods := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: testCase.cg.Namespace,
+ Name: "cp-collectd-abcde",
+ Labels: ls,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ corev1.Container{
+ Image: "collectd",
+ Name: "collectd",
+ },
+ },
+ },
+ }
+ objs = append(objs, runtime.Object(pods))
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, testCase.cg)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcg := &ReconcileCollectdGlobal{client: fc1, scheme: s}
+
+ err := rcg.updateStatus(testCase.cg)
+ assert.Equal(t, testCase.expectedError, err)
+ // Fetch the CollectdGlobal instance
+ actual := &onapv1alpha1.CollectdGlobal{}
+ err = fc1.Get(context.TODO(), req.NamespacedName, actual)
+ assert.Equal(t, testCase.expectedStatus, actual.Status.Status)
+ if testCase.createPods {
+ assert.Equal(t, []string{"cp-collectd-abcde"}, actual.Status.CollectdAgents)
+ }
+ })
+ }
+}
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go
index e0e62b87..6ad73782 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 collectdplugin
import (
@@ -255,7 +268,7 @@ func (r *ReconcileCollectdPlugin) handleDelete(reqLogger logr.Logger, cr *onapv1
}
func (r *ReconcileCollectdPlugin) updateStatus(cr *onapv1alpha1.CollectdPlugin) error {
- // Fetch the CollectdGlobal instance
+ // Fetch the CollectdPlugin instance
instance := &onapv1alpha1.CollectdPlugin{}
key := types.NamespacedName{Namespace: cr.Namespace, Name: cr.Name}
err := r.client.Get(context.TODO(), key, instance)
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller_test.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller_test.go
new file mode 100644
index 00000000..f17aa6dc
--- /dev/null
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller_test.go
@@ -0,0 +1,370 @@
+/*
+Copyright 2019 Intel Corporation.
+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 collectdplugin
+
+import (
+ "context"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+
+ onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
+ utils "collectd-operator/pkg/controller/utils"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/util/intstr"
+ "k8s.io/client-go/kubernetes/scheme"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+)
+
+const (
+ name = "cpu"
+ namespace = "test1"
+ gOpts = "BaseDir \"/opt/collectd/var/lib/collectd\"\nPIDFile \"/opt/collectd/var/run/collectd.pid\"\nPluginDir" +
+ "\"/opt/collectd/lib/collectd\"\nTypesDB \"/opt/collectd/share/collectd/types.db\"\n" +
+ "#Hostname \"localhost\"\nInterval 1 \nWriteQueueLimitHigh" +
+ "10000000\nWriteQueueLimitLow 8000000\nTimeout \"10\"\nReadThreads \"50\"\nWriteThreads" +
+ "\"50\"\n\n#Enable plugins:\n\nLoadPlugin cpufreq\nLoadPlugin ipmi\nLoadPlugin" +
+ "turbostat\nLoadPlugin irq\nLoadPlugin memcached\nLoadPlugin memory\nLoadPlugin" +
+ "processes\nLoadPlugin load\n"
+ typesCmName = "types-configmap"
+ watchLabels = "app=collectd"
+)
+
+var (
+ one = intstr.FromInt(1)
+ ls, _ = labels.ConvertSelectorToLabelsMap(watchLabels)
+ cgList = &onapv1alpha1.CollectdGlobalList{
+ Items: []onapv1alpha1.CollectdGlobal{},
+ }
+ cm = &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cp-config-map",
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Data: map[string]string{
+ "collectd.conf": "",
+ },
+ }
+ readonlyCM = &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cp-config-map-read-only",
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Data: map[string]string{
+ "collectd.conf": "",
+ },
+ }
+ typesCm = &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: typesCmName,
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Data: map[string]string{
+ "types.db": "types.db data",
+ },
+ }
+ ds = &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cp-collectd",
+ Namespace: namespace,
+ Labels: ls,
+ },
+ Spec: appsv1.DaemonSetSpec{
+ Selector: &metav1.LabelSelector{MatchLabels: ls},
+ UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
+ Type: appsv1.RollingUpdateDaemonSetStrategyType,
+ RollingUpdate: &appsv1.RollingUpdateDaemonSet{
+ MaxUnavailable: &one,
+ },
+ },
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: ls,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{{Name: "cp-collectd-1", Image: "collectd"}},
+ },
+ },
+ },
+ }
+
+ cp1 = &onapv1alpha1.CollectdPlugin{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "CollectdPlugin",
+ APIVersion: "onap.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cpu",
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdPluginSpec{
+ PluginName: "cpu",
+ PluginConf: "<Plugin cpu>\n" +
+ "ReportByCpu true\n" +
+ "ReportByState true\n" +
+ "ValuesPercentage true\n" +
+ "</Plugin>\n",
+ },
+ }
+
+ delCp1 = &onapv1alpha1.CollectdPlugin{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "CollectdPlugin",
+ APIVersion: "onap.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "cpu",
+ Namespace: namespace,
+ DeletionTimestamp: &metav1.Time{
+ Time: time.Now(),
+ },
+ Finalizers: []string{
+ utils.CollectdFinalizer,
+ },
+ },
+ Spec: onapv1alpha1.CollectdPluginSpec{
+ PluginName: "cpu",
+ PluginConf: "<Plugin cpu>\n" +
+ "ReportByCpu true\n" +
+ "ReportByState true\n" +
+ "ValuesPercentage true\n" +
+ "</Plugin>\n",
+ },
+ }
+
+ cp2 = &onapv1alpha1.CollectdPlugin{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "write_prometheus",
+ Namespace: namespace,
+ },
+ Spec: onapv1alpha1.CollectdPluginSpec{
+ PluginName: "cpu",
+ PluginConf: "<Plugin write_prometheus>\n" +
+ "Port 9103\n" +
+ "</Plugin>\n",
+ },
+ }
+
+ cpList = &onapv1alpha1.CollectdPluginList{
+ Items: []onapv1alpha1.CollectdPlugin{},
+ }
+)
+
+func TestReconcileCollectdPlugin_Reconcile(t *testing.T) {
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ tests := []struct {
+ name string
+ objs []runtime.Object
+ want reconcile.Result
+ wantErr bool
+ wantPanic bool
+ }{
+ {
+ name: "CollectdPlugin Reconcile No CR",
+ objs: getObjs(nil, []runtime.Object{cm, ds}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ },
+ {
+ name: "CollectdPlugin Add new CR cp1",
+ objs: getObjs([]onapv1alpha1.CollectdPlugin{*cp1}, []runtime.Object{cm, ds}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ },
+ {
+ name: "CollectdPlugin Delete CR cp1",
+ objs: getObjs([]onapv1alpha1.CollectdPlugin{*delCp1}, []runtime.Object{cm, ds}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ },
+ {
+ name: "CollectdPlugin Add new CR No configMap",
+ objs: getObjs([]onapv1alpha1.CollectdPlugin{*cp1}, []runtime.Object{ds}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ wantPanic: true,
+ },
+ {
+ name: "CollectdPlugin Add new CR no DaemonSet",
+ objs: getObjs([]onapv1alpha1.CollectdPlugin{*cp1}, []runtime.Object{cm}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ wantPanic: true,
+ },
+ {
+ name: "CollectdPlugin Add new CR cp2",
+ objs: getObjs([]onapv1alpha1.CollectdPlugin{*cp2}, []runtime.Object{cm, ds}),
+ want: reconcile.Result{Requeue: false},
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+
+ if tt.wantPanic {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Errorf("The code did not panic")
+ } else {
+ t.Log("Successful Panic")
+ }
+ }()
+ }
+ // Objects to track in the fake client.
+ objs := tt.objs
+
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, cp1, cpList, cgList)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcp := &ReconcileCollectdPlugin{client: fc1, scheme: s}
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+ got, err := rcp.Reconcile(req)
+ if err != nil {
+ t.Fatalf("reconcile: (%v)", err)
+ }
+ assert.Equal(t, tt.want, got)
+ })
+ }
+}
+
+// Test UpdateStatus
+func TestUpdateStatus(t *testing.T) {
+ // Set the logger to development mode for verbose logs.
+ logf.SetLogger(logf.ZapLogger(true))
+
+ os.Setenv("WATCH_LABELS", watchLabels)
+
+ testCases := []struct {
+ name string
+ cp *onapv1alpha1.CollectdPlugin
+ createPods bool
+ expectedStatus string
+ expectedError error
+ }{
+ {
+ name: "Update Status of New CR",
+ cp: getNewCPWithStatus(cp1, onapv1alpha1.Initial),
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Initial state to Created",
+ cp: getNewCPWithStatus(cp1, onapv1alpha1.Created),
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Created state - No Pods",
+ cp: getNewCPWithStatus(cp1, onapv1alpha1.Created),
+ expectedStatus: onapv1alpha1.Created,
+ expectedError: nil,
+ },
+ {
+ name: "Update Created state to Enabled",
+ cp: getNewCPWithStatus(cp1, onapv1alpha1.Created),
+ createPods: true,
+ expectedStatus: onapv1alpha1.Enabled,
+ expectedError: nil,
+ },
+ }
+ req := reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ // Objects to track in the fake client.
+ objs := []runtime.Object{
+ testCase.cp,
+ }
+ if testCase.createPods {
+ pods := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: testCase.cp.Namespace,
+ Name: "cp-collectd-abcde",
+ Labels: ls,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ corev1.Container{
+ Image: "collectd",
+ Name: "collectd",
+ },
+ },
+ },
+ }
+ objs = append(objs, runtime.Object(pods))
+ }
+ // Register operator types with the runtime scheme.
+ s := scheme.Scheme
+ s.AddKnownTypes(onapv1alpha1.SchemeGroupVersion, testCase.cp)
+
+ // Create a fake client to mock API calls
+ fc1 := fake.NewFakeClient(objs...)
+ rcp := &ReconcileCollectdPlugin{client: fc1, scheme: s}
+
+ err := rcp.updateStatus(testCase.cp)
+ assert.Equal(t, testCase.expectedError, err)
+ // Fetch the CollectdGlobal instance
+ actual := &onapv1alpha1.CollectdPlugin{}
+ err = fc1.Get(context.TODO(), req.NamespacedName, actual)
+ assert.Equal(t, testCase.expectedStatus, actual.Status.Status)
+ if testCase.createPods {
+ assert.Equal(t, []string{"cp-collectd-abcde"}, actual.Status.CollectdAgents)
+ }
+ })
+ }
+}
+
+func getNewCPWithStatus(cp *onapv1alpha1.CollectdPlugin, status string) *onapv1alpha1.CollectdPlugin {
+ cpTemp := cp.DeepCopy()
+ cpTemp.Status.Status = status
+ return cpTemp
+}
+
+func getObjs(cp []onapv1alpha1.CollectdPlugin, objs []runtime.Object) []runtime.Object {
+ cpL := cpList.DeepCopy()
+ cpL.Items = nil
+ items := append(cpL.Items, cp...)
+ cpL.Items = items
+ objs = append(objs, cpL)
+ return objs
+}
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go
index b379d916..1e73f696 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 utils
import (
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go
index c5a44c44..1892b525 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go
@@ -1,3 +1,16 @@
+/*
+Copyright 2019 Intel Corporation.
+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 utils
import (
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/predicate.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/predicate.go
index a9ec1dc4..a66e70ad 100644
--- a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/predicate.go
+++ b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/predicate.go
@@ -1,16 +1,15 @@
-// Copyright 2018 The Operator-SDK Authors
-//
-// 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.
+/*
+Copyright 2019 Intel Corporation.
+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 utils