Files
my-rook-config/pkg/operator/ceph/reporting/reporting_test.go
T
subhamkrai 08344f39f6 build: update deprecated api GetEventRecorderFor
with controller runtime latest version vO.23.0, golangci lint
is complaining about deprecated api deprecated.
This commit updates the api and adds the requried rbacs

Signed-off-by: subhamkrai <srai@redhat.com>
2026-02-09 21:48:02 +05:30

191 lines
6.3 KiB
Go

/*
Copyright 2021 The Rook Authors. All rights reserved.
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.
*/
// Reporting focuses on reporting Events, Status Conditions, and the like to users.
package reporting
import (
"bytes"
"strings"
"testing"
"time"
"github.com/coreos/pkg/capnslog"
"github.com/pkg/errors"
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/events"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
func Test_objKindOrBestGuess(t *testing.T) {
var nilCephCluster *cephv1.CephCluster = nil
tests := []struct {
name string
inObj client.Object
want string
}{
{"CephCluster with API", &cephv1.CephCluster{
TypeMeta: metav1.TypeMeta{
Kind: "CephCluster",
},
}, "CephCluster"},
{"CephCluster by inference", &cephv1.CephCluster{}, "CephCluster"},
{"CephCluster with wrong API", &cephv1.CephCluster{
TypeMeta: metav1.TypeMeta{
Kind: "WRONG",
},
}, "WRONG"},
{"untyped nil", nil, unknownKind},
{"nil CephCluster", nilCephCluster, "CephCluster"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, objKindOrBestGuess(tt.inObj))
})
}
}
func TestReportReconcileResult(t *testing.T) {
setupTest := func() (*capnslog.PackageLogger, *bytes.Buffer, *events.FakeRecorder) {
logBuf := bytes.NewBuffer([]byte{})
logFmt := capnslog.NewLogFormatter(logBuf, "", 0)
capnslog.SetFormatter(logFmt)
logger := capnslog.NewPackageLogger("github.com/rook/rook", "")
capnslog.SetGlobalLogLevel(capnslog.TRACE)
recorder := events.NewFakeRecorder(50)
return logger, logBuf, recorder
}
name := "my-cluster"
namespace := "rook-ceph"
cephCluster := &cephv1.CephCluster{
TypeMeta: metav1.TypeMeta{
Kind: "CephCluster",
APIVersion: cephv1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
reconcileRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: name, Namespace: namespace}}
successMsg := `successfully configured CephCluster "rook-ceph/my-cluster"`
successEvent := `Normal ReconcileSucceeded ` + successMsg
requeueMsg := `requeuing CephCluster "rook-ceph/my-cluster"`
requeueEvent := `Normal ReconcileRequeuing ` + requeueMsg
fakeErr := errors.New("fake-err")
errorMsg := `failed to reconcile CephCluster "rook-ceph/my-cluster". fake-err`
errorEvent := `Warning ReconcileFailed ` + errorMsg
t.Run("successful reconcile", func(t *testing.T) {
logger, logBuf, recorder := setupTest()
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
cephCluster, reconcile.Result{}, nil)
assert.NoError(t, err)
assert.True(t, result.IsZero())
assert.Equal(t, successMsg, strings.TrimSpace(logBuf.String()))
assert.Len(t, recorder.Events, 1)
assert.Equal(t, successEvent, <-recorder.Events)
})
t.Run("reconcile with error", func(t *testing.T) {
logger, logBuf, recorder := setupTest()
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
cephCluster, reconcile.Result{}, fakeErr)
assert.Error(t, err)
assert.True(t, result.IsZero())
assert.Equal(t, errorMsg, strings.TrimSpace(logBuf.String()))
assert.Len(t, recorder.Events, 1)
assert.Equal(t, errorEvent, <-recorder.Events)
})
t.Run("reconcile with requeue", func(t *testing.T) {
logger, logBuf, recorder := setupTest()
inResult := reconcile.Result{Requeue: true}
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
cephCluster, inResult, nil)
assert.NoError(t, err)
assert.Equal(t, inResult, result)
assert.Equal(t, requeueMsg, strings.TrimSpace(logBuf.String()))
assert.Len(t, recorder.Events, 1)
assert.Equal(t, requeueEvent, <-recorder.Events)
})
t.Run("failed reconcile with requeue", func(t *testing.T) {
logger, logBuf, recorder := setupTest()
inResult := reconcile.Result{RequeueAfter: 567 * time.Second}
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
cephCluster, inResult, fakeErr)
// this is the trick: when we get a request to requeue after a time _AND_ an error as input,
// we do not propagate the error to the output, _BUT_ we still record the error in log/event.
// this is so we can still report errors to users, but the controller-runtime will still
// obey our desire to reconcile with a delay
assert.NoError(t, err)
assert.Equal(t, inResult, result)
assert.Equal(t, errorMsg, strings.TrimSpace(logBuf.String()))
assert.Len(t, recorder.Events, 1)
assert.Equal(t, errorEvent, <-recorder.Events)
})
t.Run("success with empty object", func(t *testing.T) {
// success returning an empty object might be because a reconcile request is for an
// already-deleted object
logger, logBuf, recorder := setupTest()
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
&cephv1.CephCluster{}, reconcile.Result{}, nil)
assert.NoError(t, err)
assert.True(t, result.IsZero())
assert.Equal(t, successMsg, strings.TrimSpace(logBuf.String()))
assert.Len(t, recorder.Events, 1)
assert.Equal(t, successEvent, <-recorder.Events)
})
t.Run("failure with nil object", func(t *testing.T) {
// failure with a nil object might be because a reconcile returned nil for the object after
// an error accidentally
logger, logBuf, recorder := setupTest()
var obj *cephv1.CephCluster = nil
result, err := ReportReconcileResult(logger, recorder, reconcileRequest,
obj, reconcile.Result{}, fakeErr)
assert.Error(t, err)
assert.True(t, result.IsZero())
assert.Contains(t, logBuf.String(), `object associated with reconcile request CephCluster "rook-ceph/my-cluster" should not be nil`)
assert.Contains(t, logBuf.String(), errorMsg)
assert.Len(t, recorder.Events, 1)
assert.Equal(t, errorEvent, <-recorder.Events)
})
}