/pkg/backup/operator/operator_test.go
https://github.com/arangodb/kube-arangodb · Go · 371 lines · 265 code · 70 blank · 36 comment · 13 complexity · e293626292f13e0a2e638144c06080b9 MD5 · raw file
- //
- // DISCLAIMER
- //
- // Copyright 2016-2021 ArangoDB GmbH, Cologne, Germany
- //
- // 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 holder is ArangoDB GmbH, Cologne, Germany
- //
- // Author Adam Janikowski
- //
- package operator
- import (
- "context"
- "time"
- "github.com/rs/zerolog/log"
- "github.com/arangodb/kube-arangodb/pkg/backup/operator/operation"
- "github.com/stretchr/testify/assert"
- "testing"
- "github.com/stretchr/testify/require"
- core "k8s.io/api/core/v1"
- meta "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/uuid"
- "k8s.io/client-go/informers"
- "k8s.io/client-go/kubernetes/fake"
- )
- func Test_Operator_InformerProcessing(t *testing.T) {
- // Arrange
- name := string(uuid.NewUUID())
- o := NewOperator(log.Logger, name, name)
- size := 64
- objects := make([]string, size)
- for id := range objects {
- objects[id] = randomString(10)
- }
- m, i := mockSimpleObject(name, true)
- require.NoError(t, o.RegisterHandler(m))
- client := fake.NewSimpleClientset()
- informer := informers.NewSharedInformerFactory(client, 0)
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Pods().Informer(), "", "v1", "pods"))
- require.NoError(t, o.RegisterStarter(informer))
- stopCh := make(chan struct{})
- // Act
- require.NoError(t, o.Start(4, stopCh))
- for _, name := range objects {
- _, err := client.CoreV1().Pods("test").Create(context.Background(), &core.Pod{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Pod",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- }
- // Assert
- res := waitForItems(t, i, size)
- assert.Len(t, res, size)
- time.Sleep(50 * time.Millisecond)
- assert.Len(t, i, 0)
- close(stopCh)
- close(i)
- }
- func Test_Operator_MultipleInformers(t *testing.T) {
- // Arrange
- name := string(uuid.NewUUID())
- o := NewOperator(log.Logger, name, name)
- size := 16
- objects := make([]string, size)
- for id := range objects {
- objects[id] = randomString(10)
- }
- m, i := mockSimpleObject(name, true)
- require.NoError(t, o.RegisterHandler(m))
- client := fake.NewSimpleClientset()
- informer := informers.NewSharedInformerFactory(client, 0)
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Pods().Informer(), "", "v1", "pods"))
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Nodes().Informer(), "", "v1", "nodes"))
- require.NoError(t, o.RegisterStarter(informer))
- stopCh := make(chan struct{})
- // Act
- require.NoError(t, o.Start(4, stopCh))
- for _, name := range objects {
- _, err := client.CoreV1().Pods("test").Create(context.Background(), &core.Pod{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Pod",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- _, err = client.CoreV1().Nodes().Create(context.Background(), &core.Node{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Node",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- }
- // Assert
- res := waitForItems(t, i, size*2)
- assert.Len(t, res, size*2)
- time.Sleep(50 * time.Millisecond)
- assert.Len(t, i, 0)
- close(stopCh)
- close(i)
- }
- func Test_Operator_MultipleInformers_IgnoredTypes(t *testing.T) {
- // Arrange
- name := string(uuid.NewUUID())
- o := NewOperator(log.Logger, name, name)
- size := 16
- objects := make([]string, size)
- for id := range objects {
- objects[id] = randomString(10)
- }
- m, i := mockSimpleObject(name, true)
- require.NoError(t, o.RegisterHandler(m))
- client := fake.NewSimpleClientset()
- informer := informers.NewSharedInformerFactory(client, 0)
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Pods().Informer(), "", "v1", "pods"))
- require.NoError(t, o.RegisterStarter(informer))
- stopCh := make(chan struct{})
- // Act
- require.NoError(t, o.Start(4, stopCh))
- for _, name := range objects {
- _, err := client.CoreV1().Pods("test").Create(context.Background(), &core.Pod{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Pod",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- _, err = client.CoreV1().Nodes().Create(context.Background(), &core.Node{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Node",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- }
- // Assert
- res := waitForItems(t, i, size)
- assert.Len(t, res, size)
- time.Sleep(50 * time.Millisecond)
- assert.Len(t, i, 0)
- close(stopCh)
- close(i)
- }
- func Test_Operator_MultipleInformers_MultipleHandlers(t *testing.T) {
- // Arrange
- name := string(uuid.NewUUID())
- o := NewOperator(log.Logger, name, name)
- size := 16
- objects := make([]string, size)
- for id := range objects {
- objects[id] = randomString(10)
- }
- mp, ip := mockSimpleObjectFunc(name, func(item operation.Item) bool {
- return item.Kind == "pods"
- })
- require.NoError(t, o.RegisterHandler(mp))
- mn, in := mockSimpleObjectFunc(name, func(item operation.Item) bool {
- return item.Kind == "nodes"
- })
- require.NoError(t, o.RegisterHandler(mn))
- ms, is := mockSimpleObjectFunc(name, func(item operation.Item) bool {
- return item.Kind == "services"
- })
- require.NoError(t, o.RegisterHandler(ms))
- md, id := mockSimpleObject(name, true)
- require.NoError(t, o.RegisterHandler(md))
- client := fake.NewSimpleClientset()
- informer := informers.NewSharedInformerFactory(client, 0)
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Pods().Informer(), "", "v1", "pods"))
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Nodes().Informer(), "", "v1", "nodes"))
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Services().Informer(), "", "v1", "services"))
- require.NoError(t, o.RegisterInformer(informer.Core().V1().ServiceAccounts().Informer(), "", "v1", "sa"))
- require.NoError(t, o.RegisterStarter(informer))
- stopCh := make(chan struct{})
- // Act
- require.NoError(t, o.Start(4, stopCh))
- for _, name := range objects {
- _, err := client.CoreV1().Pods("test").Create(context.Background(), &core.Pod{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Pod",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- _, err = client.CoreV1().Nodes().Create(context.Background(), &core.Node{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Node",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- _, err = client.CoreV1().Services("test").Create(context.Background(), &core.Service{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Service",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- _, err = client.CoreV1().ServiceAccounts("test").Create(context.Background(), &core.ServiceAccount{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "ServiceAccount",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- }
- // Assert
- assert.Len(t, waitForItems(t, ip, size), size)
- assert.Len(t, waitForItems(t, in, size), size)
- assert.Len(t, waitForItems(t, is, size), size)
- assert.Len(t, waitForItems(t, id, size), size)
- time.Sleep(50 * time.Millisecond)
- assert.Len(t, ip, 0)
- assert.Len(t, in, 0)
- assert.Len(t, is, 0)
- assert.Len(t, id, 0)
- close(stopCh)
- close(ip)
- close(in)
- close(is)
- close(id)
- }
- func Test_Operator_InformerProcessing_Namespaced(t *testing.T) {
- // Arrange
- name := string(uuid.NewUUID())
- o := NewOperator(log.Logger, name, name)
- size := 16
- objects := make([]string, size)
- for id := range objects {
- objects[id] = randomString(10)
- }
- m, i := mockSimpleObject(name, true)
- require.NoError(t, o.RegisterHandler(m))
- client := fake.NewSimpleClientset()
- informer := informers.NewSharedInformerFactoryWithOptions(client, 0, informers.WithNamespace(objects[0]))
- require.NoError(t, o.RegisterInformer(informer.Core().V1().Pods().Informer(), "", "v1", "pods"))
- require.NoError(t, o.RegisterStarter(informer))
- stopCh := make(chan struct{})
- // Act
- require.NoError(t, o.Start(4, stopCh))
- for _, name := range objects {
- _, err := client.CoreV1().Pods(name).Create(context.Background(), &core.Pod{
- TypeMeta: meta.TypeMeta{
- APIVersion: "v1",
- Kind: "Pod",
- },
- ObjectMeta: meta.ObjectMeta{
- Name: name,
- Namespace: name,
- },
- }, meta.CreateOptions{})
- require.NoError(t, err)
- }
- // Assert
- res := waitForItems(t, i, 1)
- assert.Len(t, res, 1)
- time.Sleep(50 * time.Millisecond)
- assert.Len(t, i, 0)
- close(stopCh)
- close(i)
- }