blob: fc280591c682524a6f2887b507a82ba1a91e5129 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 broker
import (
"context"
"math/rand"
"reflect"
"strconv"
"testing"
rocketmqv1alpha1 "github.com/apache/rocketmq-operator/pkg/apis/rocketmq/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"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"
)
// TestBrokerController runs ReconcileBroker.Reconcile() against a
// fake client that tracks a Broker object.
func TestBrokerController(t *testing.T) {
// Set the logger to development mode for verbose logs.
logf.SetLogger(logf.ZapLogger(true))
var (
name = "rocketmq-operator"
namespace = "broker"
replicas int32 = 3
)
// A Broker resource with metadata and spec.
broker := &rocketmqv1alpha1.Broker{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: rocketmqv1alpha1.BrokerSpec{
Size: replicas, // Set desired number of Broker replicas.
},
}
// Objects to track in the fake client.
objs := []runtime.Object{
broker,
}
// Register operator types with the runtime scheme.
s := scheme.Scheme
s.AddKnownTypes(rocketmqv1alpha1.SchemeGroupVersion, broker)
// Create a fake client to mock API calls.
cl := fake.NewFakeClient(objs...)
// Create a ReconcileBroker object with the scheme and fake client.
r := &ReconcileBroker{client: cl, scheme: s}
// Mock request to simulate Reconcile() being called on an event for a
// watched resource .
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: name,
Namespace: namespace,
},
}
res, err := r.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")
}
// Check if deployment has been created and has the correct size.
dep := &appsv1.Deployment{}
err = cl.Get(context.TODO(), req.NamespacedName, dep)
if err != nil {
t.Fatalf("get deployment: (%v)", err)
}
dsize := *dep.Spec.Replicas
if dsize != replicas {
t.Errorf("dep size (%d) is not the expected size (%d)", dsize, replicas)
}
// Create the 3 expected pods in namespace and collect their names to check
// later.
podLabels := labelsForBroker(name)
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Labels: podLabels,
},
}
podNames := make([]string, 3)
for i := 0; i < 3; i++ {
pod.ObjectMeta.Name = name + ".pod." + strconv.Itoa(rand.Int())
podNames[i] = pod.ObjectMeta.Name
if err = cl.Create(context.TODO(), pod.DeepCopy()); err != nil {
t.Fatalf("create pod %d: (%v)", i, err)
}
}
// Reconcile again so Reconcile() checks pods and updates the Broker
// resources' Status.
res, err = r.Reconcile(req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
if res != (reconcile.Result{}) {
t.Error("reconcile did not return an empty Result")
}
// Get the updated Broker object.
broker = &rocketmqv1alpha1.Broker{}
err = r.client.Get(context.TODO(), req.NamespacedName, broker)
if err != nil {
t.Errorf("get broker: (%v)", err)
}
// Ensure Reconcile() updated the Broker's Status as expected.
nodes := broker.Status.Nodes
if !reflect.DeepEqual(podNames, nodes) {
t.Errorf("pod names %v did not match expected %v", nodes, podNames)
}
}