Skip to content

Commit

Permalink
Add ListBundles to the client interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
benluddy authored and dinhxuanvu committed Apr 16, 2020
1 parent 26e32ab commit c173bd6
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 0 deletions.
41 changes: 41 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"context"
"io"
"time"

"google.golang.org/grpc"
Expand All @@ -16,6 +17,7 @@ type Interface interface {
GetBundleInPackageChannel(ctx context.Context, packageName, channelName string) (*api.Bundle, error)
GetReplacementBundleInPackageChannel(ctx context.Context, currentName, packageName, channelName string) (*api.Bundle, error)
GetBundleThatProvides(ctx context.Context, group, version, kind string) (*api.Bundle, error)
ListBundles(ctx context.Context) (*BundleIterator, error)
HealthCheck(ctx context.Context, reconnectTimeout time.Duration) (bool, error)
Close() error
}
Expand All @@ -28,6 +30,37 @@ type Client struct {

var _ Interface = &Client{}

type BundleStream interface {
Recv() (*api.Bundle, error)
}

type BundleIterator struct {
stream BundleStream
error error
}

func NewBundleIterator(stream BundleStream) *BundleIterator {
return &BundleIterator{stream: stream}
}

func (it *BundleIterator) Next() *api.Bundle {
if it.error != nil {
return nil
}
next, err := it.stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
it.error = err
}
return next
}

func (it *BundleIterator) Error() error {
return it.error
}

func (c *Client) GetBundle(ctx context.Context, packageName, channelName, csvName string) (*api.Bundle, error) {
return c.Registry.GetBundle(ctx, &api.GetBundleRequest{PkgName: packageName, ChannelName: channelName, CsvName: csvName})
}
Expand All @@ -44,6 +77,14 @@ func (c *Client) GetBundleThatProvides(ctx context.Context, group, version, kind
return c.Registry.GetDefaultBundleThatProvides(ctx, &api.GetDefaultProviderRequest{Group: group, Version: version, Kind: kind})
}

func (c *Client) ListBundles(ctx context.Context) (*BundleIterator, error) {
stream, err := c.Registry.ListBundles(ctx, &api.ListBundlesRequest{})
if err != nil {
return nil, err
}
return NewBundleIterator(stream), nil
}

func (c *Client) Close() error {
if c.Conn == nil {
return nil
Expand Down
127 changes: 127 additions & 0 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package client

import (
"context"
"errors"
"testing"

"github.com/operator-framework/operator-registry/pkg/api"
"github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1"

"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)

type RegistryClientStub struct {
ListBundlesClient api.Registry_ListBundlesClient
error error
}

func (s *RegistryClientStub) ListPackages(ctx context.Context, in *api.ListPackageRequest, opts ...grpc.CallOption) (api.Registry_ListPackagesClient, error) {
return nil, nil
}

func (s *RegistryClientStub) GetPackage(ctx context.Context, in *api.GetPackageRequest, opts ...grpc.CallOption) (*api.Package, error) {
return nil, nil
}

func (s *RegistryClientStub) GetBundle(ctx context.Context, in *api.GetBundleRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
return nil, nil
}

func (s *RegistryClientStub) GetBundleForChannel(ctx context.Context, in *api.GetBundleInChannelRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
return nil, nil
}

func (s *RegistryClientStub) GetChannelEntriesThatReplace(ctx context.Context, in *api.GetAllReplacementsRequest, opts ...grpc.CallOption) (api.Registry_GetChannelEntriesThatReplaceClient, error) {
return nil, nil
}

func (s *RegistryClientStub) GetBundleThatReplaces(ctx context.Context, in *api.GetReplacementRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
return nil, nil
}

func (s *RegistryClientStub) GetChannelEntriesThatProvide(ctx context.Context, in *api.GetAllProvidersRequest, opts ...grpc.CallOption) (api.Registry_GetChannelEntriesThatProvideClient, error) {
return nil, nil
}

func (s *RegistryClientStub) GetLatestChannelEntriesThatProvide(ctx context.Context, in *api.GetLatestProvidersRequest, opts ...grpc.CallOption) (api.Registry_GetLatestChannelEntriesThatProvideClient, error) {
return nil, nil
}

func (s *RegistryClientStub) GetDefaultBundleThatProvides(ctx context.Context, in *api.GetDefaultProviderRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
return nil, nil
}

func (s *RegistryClientStub) ListBundles(ctx context.Context, in *api.ListBundlesRequest, opts ...grpc.CallOption) (api.Registry_ListBundlesClient, error) {
return s.ListBundlesClient, s.error
}

func (s *RegistryClientStub) Check(ctx context.Context, in *grpc_health_v1.HealthCheckRequest, opts ...grpc.CallOption) (*grpc_health_v1.HealthCheckResponse, error) {
return nil, nil
}

type BundleReceiverStub struct {
Bundle *api.Bundle
error error
grpc.ClientStream
}

func (s *BundleReceiverStub) Recv() (*api.Bundle, error) {
return s.Bundle, s.error
}

func TestListBundlesError(t *testing.T) {
expected := errors.New("test error")
stub := &RegistryClientStub{
error: expected,
}
c := Client{
Registry: stub,
Health: stub,
}

_, actual := c.ListBundles(context.TODO())
require.Equal(t, expected, actual)
}

func TestListBundlesRecvError(t *testing.T) {
expected := errors.New("test error")
rstub := &BundleReceiverStub{
error: expected,
}
cstub := &RegistryClientStub{
ListBundlesClient: rstub,
}
c := Client{
Registry: cstub,
Health: cstub,
}

it, err := c.ListBundles(context.TODO())
require.NoError(t, err)

require.Nil(t, it.Next())
require.Equal(t, expected, it.Error())
}

func TestListBundlesNext(t *testing.T) {
expected := &api.Bundle{CsvName: "test"}
rstub := &BundleReceiverStub{
Bundle: expected,
}
cstub := &RegistryClientStub{
ListBundlesClient: rstub,
}
c := Client{
Registry: cstub,
Health: cstub,
}

it, err := c.ListBundles(context.TODO())
require.NoError(t, err)

actual := it.Next()
require.NoError(t, it.Error())
require.Equal(t, expected, actual)
}
35 changes: 35 additions & 0 deletions pkg/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,41 @@ func TestGetDefaultBundleThatProvides(t *testing.T) {
EqualBundles(t, *expected, *bundle)
}

func TestListBundles(t *testing.T) {
require := require.New(t)

c, conn := client(t)
defer conn.Close()

stream, err := c.ListBundles(context.TODO(), &api.ListBundlesRequest{})
require.NoError(err)

expected := []string{
"etcdoperator.v0.6.1",
"strimzi-cluster-operator.v0.11.1",
"etcdoperator.v0.9.2",
"etcdoperator.v0.9.0",
"prometheusoperator.0.22.2",
"prometheusoperator.0.15.0",
"prometheusoperator.0.14.0",
"strimzi-cluster-operator.v0.11.0",
"strimzi-cluster-operator.v0.12.1",
"strimzi-cluster-operator.v0.12.2",
}

var names []string
for range expected {
bundle, err := stream.Recv()
require.NoError(err)
names = append(names, bundle.CsvName)
}

_, err = stream.Recv()
require.Equal(io.EOF, err)

require.ElementsMatch(expected, names)
}

func EqualBundles(t *testing.T, expected, actual api.Bundle) {
require.ElementsMatch(t, expected.ProvidedApis, actual.ProvidedApis)
require.ElementsMatch(t, expected.RequiredApis, actual.RequiredApis)
Expand Down

0 comments on commit c173bd6

Please sign in to comment.