"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
if cl.MaxPageSize > 0 && len(resp.Items) >= cl.MaxPageSize {
break
}
- if options.Limit >= 0 && len(resp.Items) >= options.Limit {
+ if options.Limit >= 0 && int64(len(resp.Items)) >= options.Limit {
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)
}
}
type listTrial struct {
count string
- limit int
- offset int
+ limit int64
+ offset int64
order []string
filters []arvados.Filter
+ selectfields []string
expectUUIDs []string
expectCalls []int // number of API calls to backends
expectStatus int
})
}
+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",
})
}
+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",
})
}
+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",
}
func (s *CollectionListSuite) TestCollectionListMultiSiteWithLimit(c *check.C) {
- for _, limit := range []int{0, 1, 2} {
+ for _, limit := range []int64{0, 1, 2} {
s.test(c, listTrial{
count: "none",
limit: limit,
}
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,
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,
})