Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests #111

Merged
merged 1 commit into from
Jun 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions pkg/stores/proxy/proxy_store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package proxy

import (
"fmt"
"net/http"
"testing"
"time"

"github.com/pkg/errors"
"github.com/rancher/apiserver/pkg/types"
"github.com/rancher/steve/pkg/client"
"github.com/rancher/wrangler/pkg/schemas"
"github.com/stretchr/testify/assert"
"golang.org/x/sync/errgroup"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
schema2 "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/dynamic/fake"
"k8s.io/client-go/rest"
clientgotesting "k8s.io/client-go/testing"
)

var c *watch.FakeWatcher

type testFactory struct {
*client.Factory

fakeClient *fake.FakeDynamicClient
}

func TestWatchNamesErrReceive(t *testing.T) {
testClientFactory, err := client.NewFactory(&rest.Config{}, false)
assert.Nil(t, err)

fakeClient := fake.NewSimpleDynamicClient(runtime.NewScheme())
c = watch.NewFakeWithChanSize(5, true)
defer c.Stop()
errMsgsToSend := []string{"err1", "err2", "err3"}
c.Add(&v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "testsecret1"}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Both testsecret1 and testsecret2 are part of the names we are watching. Would also be good to feed an event through with a name that we aren't watching for, to make sure WatchName doesn't return that object.

In addition, it would be good to return an object which errors when you call meta.Accessor() on it, to cover that case.

Marking as a nit due to priority, timeline, and that these are backfill cases.

for index := range errMsgsToSend {
c.Error(&metav1.Status{
Message: errMsgsToSend[index],
})
}
c.Add(&v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "testsecret2"}})
fakeClient.PrependWatchReactor("*", func(action clientgotesting.Action) (handled bool, ret watch.Interface, err error) {
return true, c, nil
})
testStore := Store{
clientGetter: &testFactory{Factory: testClientFactory,
fakeClient: fakeClient,
},
}
apiSchema := &types.APISchema{Schema: &schemas.Schema{Attributes: map[string]interface{}{"table": "something"}}}
wc, err := testStore.WatchNames(&types.APIRequest{Namespace: "", Schema: apiSchema, Request: &http.Request{}}, apiSchema, types.WatchRequest{}, sets.NewString("testsecret1", "testsecret2"))
assert.Nil(t, err)

eg := errgroup.Group{}
eg.Go(func() error { return receiveUntil(wc, 5*time.Second) })

err = eg.Wait()
assert.Nil(t, err)

assert.Equal(t, 0, len(c.ResultChan()), "Expected all secrets to have been received")
}

func (t *testFactory) TableAdminClientForWatch(ctx *types.APIRequest, schema *types.APISchema, namespace string, warningHandler rest.WarningHandler) (dynamic.ResourceInterface, error) {
return t.fakeClient.Resource(schema2.GroupVersionResource{}), nil
}

func receiveUntil(wc chan watch.Event, d time.Duration) error {
timer := time.NewTicker(d)
defer timer.Stop()
secretNames := []string{"testsecret1", "testsecret2"}
for {
select {
case event, ok := <-wc:
if !ok {
return errors.New("watch chan should not have been closed")
}

if event.Type == watch.Error {
return errors.New(fmt.Sprintf("watch chan should not have sent events of type [%s]", watch.Error))
}
secret, ok := event.Object.(*v1.Secret)
if !ok {
continue
}
if secret.Name == secretNames[0] {
secretNames = secretNames[1:]
}
if len(secretNames) == 0 {
return nil
}
continue
case <-timer.C:
return errors.New("timed out waiting to receiving objects from chan")
}
}
}