kubectl-persistent-logger/logs/watcher_test.go

138 lines
4.4 KiB
Go
Raw Normal View History

2022-05-30 10:10:58 +00:00
package logs_test
import (
"bytes"
"context"
2022-06-01 17:19:55 +00:00
"errors"
"io"
"strings"
2022-05-30 10:10:58 +00:00
"testing"
"time"
"git.netflux.io/rob/kubectl-persistent-logger/logs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
testclient "k8s.io/client-go/kubernetes/fake"
k8stest "k8s.io/client-go/testing"
)
2022-06-01 17:19:55 +00:00
type mockPodWatcher struct{ err error }
func (m *mockPodWatcher) WatchPods(ctx context.Context) error { return m.err }
func (m *mockPodWatcher) Close() {}
func mockPodwatcherFunc(err error) logs.PodWatcherFunc {
return func(logs.KubernetesClient, string, *metav1.LabelSelector, io.Writer) logs.PodWatcherInterface {
return &mockPodWatcher{err: err}
}
}
func TestWatcherAllowNonExistent(t *testing.T) {
clientset := testclient.NewSimpleClientset()
var buf bytes.Buffer
client := logs.KubernetesClient{Interface: clientset}
2022-06-01 20:04:20 +00:00
watcher := logs.NewWatcher("mydeployment", "mycontainer", true, client, mockPodwatcherFunc(nil), &buf)
2022-06-01 17:19:55 +00:00
err := watcher.Watch(context.Background())
assert.EqualError(t, err, `deployments.apps "mydeployment" not found`)
}
func TestWatcherPodWatcherError(t *testing.T) {
deploymentsWatcher := watch.NewFake()
2022-05-30 10:10:58 +00:00
clientset := testclient.NewSimpleClientset(
2022-06-01 17:19:55 +00:00
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "mydeployment", Namespace: "default"}},
2022-05-30 10:10:58 +00:00
)
2022-06-01 17:19:55 +00:00
clientset.PrependWatchReactor("deployments", k8stest.DefaultWatchReactor(deploymentsWatcher, nil))
2022-05-30 10:10:58 +00:00
2022-06-01 17:19:55 +00:00
var buf bytes.Buffer
client := logs.KubernetesClient{Interface: clientset}
wantErr := errors.New("foo")
2022-06-01 20:04:20 +00:00
watcher := logs.NewWatcher("mydeployment", "mycontainer", true, client, mockPodwatcherFunc(wantErr), &buf)
2022-05-30 10:10:58 +00:00
go func() {
2022-06-01 17:19:55 +00:00
defer deploymentsWatcher.Stop()
deployment := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "mydeployment", Namespace: "default"}}
deploymentsWatcher.Add(deployment)
}()
err := watcher.Watch(context.Background())
assert.EqualError(t, err, wantErr.Error())
}
2022-06-04 00:27:20 +00:00
func TestWatcherClosedChannel(t *testing.T) {
deploymentsWatcher := watch.NewFake()
clientset := testclient.NewSimpleClientset(
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "mydeployment", Namespace: "default"}},
)
clientset.PrependWatchReactor("deployments", k8stest.DefaultWatchReactor(deploymentsWatcher, nil))
var buf bytes.Buffer
client := logs.KubernetesClient{Interface: clientset}
watcher := logs.NewWatcher("mydeployment", "mycontainer", true, client, nil, &buf)
go deploymentsWatcher.Stop()
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
defer cancel()
err := watcher.Watch(ctx)
require.Equal(t, context.DeadlineExceeded, err)
assert.Equal(t, "", buf.String())
}
2022-06-01 17:19:55 +00:00
func TestWatcherWithPodWatcher(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
deploymentsWatcher := watch.NewFake()
2022-06-02 17:23:47 +00:00
defer deploymentsWatcher.Stop()
2022-06-01 17:19:55 +00:00
podsWatcher := watch.NewFake()
2022-06-02 17:23:47 +00:00
defer podsWatcher.Stop()
2022-06-01 17:19:55 +00:00
clientset := testclient.NewSimpleClientset()
clientset.PrependWatchReactor("pods", k8stest.DefaultWatchReactor(podsWatcher, nil))
clientset.PrependWatchReactor("deployments", k8stest.DefaultWatchReactor(deploymentsWatcher, nil))
go func() {
2022-06-02 17:23:47 +00:00
defer cancel()
2022-06-01 17:19:55 +00:00
deployment := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "mydeployment", Namespace: "default"}}
deploymentsWatcher.Add(deployment)
time.Sleep(time.Millisecond * 250)
pods := []*corev1.Pod{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"},
Status: corev1.PodStatus{Phase: corev1.PodRunning},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "default"},
Status: corev1.PodStatus{Phase: corev1.PodRunning},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "default"},
Status: corev1.PodStatus{Phase: corev1.PodPending},
},
}
2022-05-30 10:10:58 +00:00
for _, pod := range pods {
2022-06-01 17:19:55 +00:00
podsWatcher.Add(pod)
time.Sleep(time.Millisecond * 250)
2022-05-30 10:10:58 +00:00
}
2022-06-01 17:19:55 +00:00
}()
2022-05-30 10:10:58 +00:00
var buf bytes.Buffer
2022-06-01 17:19:55 +00:00
client := logs.KubernetesClient{Interface: clientset}
2022-06-01 20:04:20 +00:00
watcher := logs.NewWatcher("mydeployment", "mycontainer", false, client, logs.NewPodWatcher, &buf)
2022-05-30 10:10:58 +00:00
err := watcher.Watch(ctx)
2022-06-01 17:19:55 +00:00
require.EqualError(t, err, context.Canceled.Error())
assert.ElementsMatch(t, []string{"[foo] fake logs", "[bar] fake logs"}, splitBuf(&buf))
}
func splitBuf(buf *bytes.Buffer) []string {
return strings.Split(strings.TrimSpace(buf.String()), "\n")
2022-05-30 10:10:58 +00:00
}