Merge pull request #1 from arvados/master
[arvados.git] / lib / controller / federation / list_test.go
index c9b981fc15fed27d5fb75131894a2cff6cd77a41..ce84378a3cbb79d7a4ae894f966bc627bef2b08d 100644 (file)
@@ -8,74 +8,15 @@ import (
        "context"
        "fmt"
        "net/http"
-       "net/url"
-       "os"
-       "testing"
-
-       "git.curoverse.com/arvados.git/lib/controller/router"
-       "git.curoverse.com/arvados.git/lib/controller/rpc"
-       "git.curoverse.com/arvados.git/sdk/go/arvados"
-       "git.curoverse.com/arvados.git/sdk/go/arvadostest"
-       "git.curoverse.com/arvados.git/sdk/go/auth"
-       "git.curoverse.com/arvados.git/sdk/go/ctxlog"
-       "git.curoverse.com/arvados.git/sdk/go/httpserver"
-       check "gopkg.in/check.v1"
-)
-
-// Gocheck boilerplate
-func Test(t *testing.T) {
-       check.TestingT(t)
-}
+       "reflect"
+       "sort"
 
-var (
-       _ = check.Suite(&FederationSuite{})
-       _ = check.Suite(&CollectionListSuite{})
+       "git.arvados.org/arvados.git/sdk/go/arvados"
+       "git.arvados.org/arvados.git/sdk/go/arvadostest"
+       check "gopkg.in/check.v1"
 )
 
-type FederationSuite struct {
-       cluster *arvados.Cluster
-       ctx     context.Context
-       fed     *Conn
-}
-
-func (s *FederationSuite) SetUpTest(c *check.C) {
-       s.cluster = &arvados.Cluster{
-               ClusterID: "aaaaa",
-               RemoteClusters: map[string]arvados.RemoteCluster{
-                       "aaaaa": arvados.RemoteCluster{
-                               Host: os.Getenv("ARVADOS_API_HOST"),
-                       },
-               },
-       }
-       arvadostest.SetServiceURL(&s.cluster.Services.RailsAPI, "https://"+os.Getenv("ARVADOS_TEST_API_HOST"))
-       s.cluster.TLS.Insecure = true
-       s.cluster.API.MaxItemsPerResponse = 3
-
-       ctx := context.Background()
-       ctx = ctxlog.Context(ctx, ctxlog.TestLogger(c))
-       ctx = auth.NewContext(ctx, &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
-       s.ctx = ctx
-
-       s.fed = New(s.cluster)
-}
-
-func (s *FederationSuite) addDirectRemote(c *check.C, id string, backend backend) {
-       s.cluster.RemoteClusters[id] = arvados.RemoteCluster{
-               Host: "in-process.local",
-       }
-       s.fed.remotes[id] = backend
-}
-
-func (s *FederationSuite) addHTTPRemote(c *check.C, id string, backend backend) {
-       srv := httpserver.Server{Addr: ":"}
-       srv.Handler = router.New(backend)
-       c.Check(srv.Start(), check.IsNil)
-       s.cluster.RemoteClusters[id] = arvados.RemoteCluster{
-               Host:  srv.Addr,
-               Proxy: true,
-       }
-       s.fed.remotes[id] = rpc.NewConn(id, &url.URL{Scheme: "http", Host: srv.Addr}, true, saltedTokenProvider(s.fed.local, id))
-}
+var _ = check.Suite(&CollectionListSuite{})
 
 type collectionLister struct {
        arvadostest.APIStub
@@ -121,6 +62,13 @@ func (cl *collectionLister) CollectionList(ctx context.Context, options arvados.
                        break
                }
                if cl.matchFilters(c, options.Filters) {
+                       if reflect.DeepEqual(options.Select, []string{"uuid", "name"}) {
+                               c = arvados.Collection{UUID: c.UUID, Name: c.Name}
+                       } else if reflect.DeepEqual(options.Select, []string{"name"}) {
+                               c = arvados.Collection{Name: c.Name}
+                       } else if len(options.Select) > 0 {
+                               panic(fmt.Sprintf("not implemented: options=%#v", options))
+                       }
                        resp.Items = append(resp.Items, c)
                }
        }
@@ -171,6 +119,7 @@ type listTrial struct {
        offset       int
        order        []string
        filters      []arvados.Filter
+       selectfields []string
        expectUUIDs  []string
        expectCalls  []int // number of API calls to backends
        expectStatus int
@@ -205,6 +154,17 @@ func (s *CollectionListSuite) TestCollectionListOneRemote(c *check.C) {
        })
 }
 
+func (s *CollectionListSuite) TestCollectionListOneLocalDeselectingUUID(c *check.C) {
+       s.test(c, listTrial{
+               count:        "none",
+               limit:        -1,
+               filters:      []arvados.Filter{{"uuid", "=", s.uuids[0][0]}},
+               selectfields: []string{"name"},
+               expectUUIDs:  []string{""}, // select=name is honored
+               expectCalls:  []int{1, 0, 0},
+       })
+}
+
 func (s *CollectionListSuite) TestCollectionListOneLocalUsingInOperator(c *check.C) {
        s.test(c, listTrial{
                count:       "none",
@@ -225,6 +185,17 @@ func (s *CollectionListSuite) TestCollectionListOneRemoteUsingInOperator(c *chec
        })
 }
 
+func (s *CollectionListSuite) TestCollectionListOneRemoteDeselectingUUID(c *check.C) {
+       s.test(c, listTrial{
+               count:        "none",
+               limit:        -1,
+               filters:      []arvados.Filter{{"uuid", "=", s.uuids[1][0]}},
+               selectfields: []string{"name"},
+               expectUUIDs:  []string{s.uuids[1][0]}, // uuid is returned, despite not being selected
+               expectCalls:  []int{0, 1, 0},
+       })
+}
+
 func (s *CollectionListSuite) TestCollectionListOneLocalOneRemote(c *check.C) {
        s.test(c, listTrial{
                count:       "none",
@@ -235,6 +206,17 @@ func (s *CollectionListSuite) TestCollectionListOneLocalOneRemote(c *check.C) {
        })
 }
 
+func (s *CollectionListSuite) TestCollectionListOneLocalOneRemoteDeselectingUUID(c *check.C) {
+       s.test(c, listTrial{
+               count:        "none",
+               limit:        -1,
+               filters:      []arvados.Filter{{"uuid", "in", []string{s.uuids[0][0], s.uuids[1][0]}}},
+               selectfields: []string{"name"},
+               expectUUIDs:  []string{s.uuids[0][0], s.uuids[1][0]}, // uuid is returned, despite not being selected
+               expectCalls:  []int{1, 1, 0},
+       })
+}
+
 func (s *CollectionListSuite) TestCollectionListTwoRemotes(c *check.C) {
        s.test(c, listTrial{
                count:       "none",
@@ -398,7 +380,7 @@ func (s *CollectionListSuite) TestCollectionListRemoteUnknown(c *check.C) {
 }
 
 func (s *CollectionListSuite) TestCollectionListRemoteError(c *check.C) {
-       s.addDirectRemote(c, "bbbbb", &arvadostest.APIStub{})
+       s.addDirectRemote(c, "bbbbb", &arvadostest.APIStub{Error: fmt.Errorf("stub backend error")})
        s.test(c, listTrial{
                count: "none",
                limit: -1,
@@ -416,20 +398,24 @@ func (s *CollectionListSuite) test(c *check.C, trial listTrial) {
                Offset:  trial.offset,
                Order:   trial.order,
                Filters: trial.filters,
+               Select:  trial.selectfields,
        })
        if trial.expectStatus != 0 {
                c.Assert(err, check.NotNil)
-               err, _ := err.(interface{ HTTPStatus() int })
-               c.Assert(err, check.NotNil) // err must implement HTTPStatus()
+               err, ok := err.(interface{ HTTPStatus() int })
+               c.Assert(ok, check.Equals, true) // err must implement interface{ HTTPStatus() int }
                c.Check(err.HTTPStatus(), check.Equals, trial.expectStatus)
                c.Logf("returned error is %#v", err)
                c.Logf("returned error string is %q", err)
        } else {
                c.Check(err, check.IsNil)
-               var expectItems []arvados.Collection
+               expectItems := []arvados.Collection{}
                for _, uuid := range trial.expectUUIDs {
                        expectItems = append(expectItems, arvados.Collection{UUID: uuid})
                }
+               // expectItems is sorted by UUID, so sort resp.Items
+               // by UUID before checking DeepEquals.
+               sort.Slice(resp.Items, func(i, j int) bool { return resp.Items[i].UUID < resp.Items[j].UUID })
                c.Check(resp, check.DeepEquals, arvados.CollectionList{
                        Items: expectItems,
                })