15720: Defer user listing to login cluster, cache results locally.
authorTom Clegg <tclegg@veritasgenetics.com>
Mon, 18 Nov 2019 16:22:06 +0000 (11:22 -0500)
committerTom Clegg <tclegg@veritasgenetics.com>
Mon, 18 Nov 2019 16:22:11 +0000 (11:22 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

14 files changed:
lib/controller/federation/conn.go
lib/controller/federation/federation_test.go [new file with mode: 0644]
lib/controller/federation/list_test.go
lib/controller/federation/login_test.go
lib/controller/federation/user_test.go [new file with mode: 0644]
sdk/go/arvados/user.go
sdk/go/arvadostest/api.go
sdk/go/arvadostest/fixtures.go
sdk/python/tests/run_test_server.py
services/keep-balance/integration_test.go
services/keepstore/handler_test.go
services/keepstore/mounts_test.go
services/keepstore/proxy_remote_test.go
tools/keep-rsync/keep-rsync_test.go

index 9d01f1f7c58230c7865688014ab01644bbae2c74..47ae0ba9ec3ab4c59aa09191d884fdc973345a55 100644 (file)
@@ -323,8 +323,82 @@ func (conn *Conn) SpecimenDelete(ctx context.Context, options arvados.DeleteOpti
        return conn.chooseBackend(options.UUID).SpecimenDelete(ctx, options)
 }
 
+var userAttrsCachedFromLoginCluster = map[string]bool{
+       "created_at":              true,
+       "email":                   true,
+       "first_name":              true,
+       "is_active":               true,
+       "is_admin":                true,
+       "last_name":               true,
+       "modified_at":             true,
+       "modified_by_client_uuid": true,
+       "modified_by_user_uuid":   true,
+       "prefs":                   true,
+       "username":                true,
+
+       "full_name":    false,
+       "identity_url": false,
+       "is_invited":   false,
+       "owner_uuid":   false,
+       "uuid":         false,
+}
+
 func (conn *Conn) UserList(ctx context.Context, options arvados.ListOptions) (arvados.UserList, error) {
-       return conn.generated_UserList(ctx, options)
+       logger := ctxlog.FromContext(ctx)
+       if id := conn.cluster.Login.LoginCluster; id != "" && id != conn.cluster.ClusterID {
+               resp, err := conn.chooseBackend(id).UserList(ctx, options)
+               if err != nil {
+                       return resp, err
+               }
+               ctxRoot := auth.NewContext(ctx, &auth.Credentials{Tokens: []string{conn.cluster.SystemRootToken}})
+               for _, user := range resp.Items {
+                       if !strings.HasPrefix(user.UUID, id) {
+                               continue
+                       }
+                       logger.Debug("cache user info for uuid %q", user.UUID)
+                       var allFields map[string]interface{}
+                       buf, err := json.Marshal(user)
+                       if err != nil {
+                               return arvados.UserList{}, fmt.Errorf("error encoding user record from remote response: %s", err)
+                       }
+                       err = json.Unmarshal(buf, &allFields)
+                       if err != nil {
+                               return arvados.UserList{}, fmt.Errorf("error transcoding user record from remote response: %s", err)
+                       }
+                       updates := allFields
+                       if len(options.Select) > 0 {
+                               updates = map[string]interface{}{}
+                               for _, k := range options.Select {
+                                       if v, ok := allFields[k]; ok && userAttrsCachedFromLoginCluster[k] {
+                                               updates[k] = v
+                                       }
+                               }
+                       } else {
+                               for k := range updates {
+                                       if !userAttrsCachedFromLoginCluster[k] {
+                                               delete(updates, k)
+                                       }
+                               }
+                       }
+                       _, err = conn.local.UserUpdate(ctxRoot, arvados.UpdateOptions{
+                               UUID:  user.UUID,
+                               Attrs: updates,
+                       })
+                       if errStatus(err) == http.StatusNotFound {
+                               updates["uuid"] = user.UUID
+                               _, err = conn.local.UserCreate(ctxRoot, arvados.CreateOptions{
+                                       Attrs: updates,
+                               })
+                       }
+                       if err != nil {
+                               logger.WithError(err).WithField("UUID", user.UUID).Error("error updating local user record")
+                               return arvados.UserList{}, fmt.Errorf("error updating local user record: %s", err)
+                       }
+               }
+               return resp, nil
+       } else {
+               return conn.generated_UserList(ctx, options)
+       }
 }
 
 func (conn *Conn) UserCreate(ctx context.Context, options arvados.CreateOptions) (arvados.User, error) {
diff --git a/lib/controller/federation/federation_test.go b/lib/controller/federation/federation_test.go
new file mode 100644 (file)
index 0000000..60164b4
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package federation
+
+import (
+       "context"
+       "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)
+}
+
+// FederationSuite does some generic setup/teardown. Don't add Test*
+// methods to FederationSuite itself.
+type FederationSuite struct {
+       cluster *arvados.Cluster
+       ctx     context.Context
+       fed     *Conn
+}
+
+func (s *FederationSuite) SetUpTest(c *check.C) {
+       s.cluster = &arvados.Cluster{
+               ClusterID:       "aaaaa",
+               SystemRootToken: arvadostest.SystemRootToken,
+               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{
+               Scheme: "http",
+               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))
+}
index c9b981fc15fed27d5fb75131894a2cff6cd77a41..5a630a9450ef861ed7c91c5f001f3fa642378638 100644 (file)
@@ -8,74 +8,13 @@ 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)
-}
-
-var (
-       _ = check.Suite(&FederationSuite{})
-       _ = check.Suite(&CollectionListSuite{})
-)
-
-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
index e001014e2181a142cbab2bd4ad65343578f5e77d..f83f5fb9359bd0765a84dc86cde1f94b35ab9655 100644 (file)
@@ -13,7 +13,13 @@ import (
        check "gopkg.in/check.v1"
 )
 
-func (s *FederationSuite) TestDeferToLoginCluster(c *check.C) {
+var _ = check.Suite(&LoginSuite{})
+
+type LoginSuite struct {
+       FederationSuite
+}
+
+func (s *LoginSuite) TestDeferToLoginCluster(c *check.C) {
        s.addHTTPRemote(c, "zhome", &arvadostest.APIStub{})
        s.cluster.Login.LoginCluster = "zhome"
 
diff --git a/lib/controller/federation/user_test.go b/lib/controller/federation/user_test.go
new file mode 100644 (file)
index 0000000..993be9b
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package federation
+
+import (
+       "encoding/json"
+       "errors"
+       "net/url"
+       "os"
+       "strings"
+
+       "git.curoverse.com/arvados.git/lib/controller/rpc"
+       "git.curoverse.com/arvados.git/sdk/go/arvados"
+       "git.curoverse.com/arvados.git/sdk/go/arvadostest"
+       check "gopkg.in/check.v1"
+)
+
+var _ = check.Suite(&UserSuite{})
+
+type UserSuite struct {
+       FederationSuite
+}
+
+func (s *UserSuite) TestLoginClusterUserList(c *check.C) {
+       s.cluster.ClusterID = "local"
+       s.cluster.Login.LoginCluster = "zzzzz"
+       s.fed = New(s.cluster)
+       s.addDirectRemote(c, "zzzzz", rpc.NewConn("zzzzz", &url.URL{Scheme: "https", Host: os.Getenv("ARVADOS_API_HOST")}, true, rpc.PassthroughTokenProvider))
+
+       for _, updateFail := range []bool{false, true} {
+               for _, opts := range []arvados.ListOptions{
+                       {Offset: 0, Limit: -1, Select: nil},
+                       {Offset: 1, Limit: 1, Select: nil},
+                       {Offset: 0, Limit: 2, Select: []string{"uuid"}},
+                       {Offset: 0, Limit: 2, Select: []string{"uuid", "email"}},
+               } {
+                       c.Logf("updateFail %v, opts %#v", updateFail, opts)
+                       spy := arvadostest.NewProxy(c, s.cluster.Services.RailsAPI)
+                       stub := &arvadostest.APIStub{Error: errors.New("local cluster failure")}
+                       if updateFail {
+                               s.fed.local = stub
+                       } else {
+                               s.fed.local = rpc.NewConn(s.cluster.ClusterID, spy.URL, true, rpc.PassthroughTokenProvider)
+                       }
+                       userlist, err := s.fed.UserList(s.ctx, opts)
+                       if updateFail && err == nil {
+                               // All local updates fail, so the only
+                               // cases expected to succeed are the
+                               // ones with 0 results.
+                               c.Check(userlist.Items, check.HasLen, 0)
+                               c.Check(stub.Calls(nil), check.HasLen, 0)
+                       } else if updateFail {
+                               c.Logf("... err %#v", err)
+                               calls := stub.Calls(stub.UserUpdate)
+                               if c.Check(calls, check.HasLen, 1) {
+                                       c.Logf("... stub.UserUpdate called with options: %#v", calls[0].Options)
+                                       shouldUpdate := map[string]bool{
+                                               "uuid":       false,
+                                               "email":      true,
+                                               "first_name": true,
+                                               "last_name":  true,
+                                               "is_admin":   true,
+                                               "is_active":  true,
+                                               "prefs":      true,
+                                               // can't safely update locally
+                                               "owner_uuid":   false,
+                                               "identity_url": false,
+                                               // virtual attrs
+                                               "full_name":  false,
+                                               "is_invited": false,
+                                       }
+                                       if opts.Select != nil {
+                                               // Only the selected
+                                               // fields (minus uuid)
+                                               // should be updated.
+                                               for k := range shouldUpdate {
+                                                       shouldUpdate[k] = false
+                                               }
+                                               for _, k := range opts.Select {
+                                                       if k != "uuid" {
+                                                               shouldUpdate[k] = true
+                                                       }
+                                               }
+                                       }
+                                       for k, shouldFind := range shouldUpdate {
+                                               _, found := calls[0].Options.(arvados.UpdateOptions).Attrs[k]
+                                               c.Check(found, check.Equals, shouldFind, check.Commentf("offending attr: %s", k))
+                                       }
+                               }
+                       } else {
+                               updates := 0
+                               for _, d := range spy.RequestDumps {
+                                       d := string(d)
+                                       if strings.Contains(d, "PATCH /arvados/v1/users/zzzzz-tpzed-") {
+                                               c.Check(d, check.Matches, `(?ms).*Authorization: Bearer `+arvadostest.SystemRootToken+`.*`)
+                                               updates++
+                                       }
+                               }
+                               c.Check(err, check.IsNil)
+                               c.Check(updates, check.Equals, len(userlist.Items))
+                               c.Logf("... response items %#v", userlist.Items)
+                       }
+               }
+       }
+}
+
+// userAttrsCachedFromLoginCluster must have an entry for every field
+// in the User struct.
+func (s *UserSuite) TestUserAttrsUpdateWhitelist(c *check.C) {
+       buf, err := json.Marshal(&arvados.User{})
+       c.Assert(err, check.IsNil)
+       var allFields map[string]interface{}
+       err = json.Unmarshal(buf, &allFields)
+       c.Assert(err, check.IsNil)
+       for k := range allFields {
+               _, ok := userAttrsCachedFromLoginCluster[k]
+               c.Check(ok, check.Equals, true, check.Commentf("field name %q missing from userAttrsCachedFromLoginCluster", k))
+       }
+}
index 27d2b28a42b6c5c4312d0aa16624e8061103ac5d..30bc094d07c95e91b9a930c0bb923e4d4d6d908e 100644 (file)
@@ -4,13 +4,26 @@
 
 package arvados
 
+import "time"
+
 // User is an arvados#user record
 type User struct {
-       UUID     string `json:"uuid"`
-       IsActive bool   `json:"is_active"`
-       IsAdmin  bool   `json:"is_admin"`
-       Username string `json:"username"`
-       Email    string `json:"email"`
+       UUID                 string                 `json:"uuid"`
+       IsActive             bool                   `json:"is_active"`
+       IsAdmin              bool                   `json:"is_admin"`
+       Username             string                 `json:"username"`
+       Email                string                 `json:"email"`
+       FullName             string                 `json:"full_name"`
+       FirstName            string                 `json:"first_name"`
+       LastName             string                 `json:"last_name"`
+       IdentityURL          string                 `json:"identity_url"`
+       IsInvited            bool                   `json:"is_invited"`
+       OwnerUUID            string                 `json:"owner_uuid"`
+       CreatedAt            time.Time              `json:"created_at"`
+       ModifiedAt           time.Time              `json:"modified_at"`
+       ModifiedByUserUUID   string                 `json:"modified_by_user_uuid"`
+       ModifiedByClientUUID string                 `json:"modified_by_client_uuid"`
+       Prefs                map[string]interface{} `json:"prefs"`
 }
 
 // UserList is an arvados#userList resource.
index 96b7c75f1ab35a48ccb12d5355ebc078892d8b1a..f18af8caaa65806699559b003c8beb886f7eaff9 100644 (file)
@@ -185,7 +185,6 @@ func (as *APIStub) Calls(method interface{}) []APIStubCall {
        defer as.mtx.Unlock()
        var calls []APIStubCall
        for _, call := range as.calls {
-
                if method == nil || (runtime.FuncForPC(reflect.ValueOf(call.Method).Pointer()).Name() ==
                        runtime.FuncForPC(reflect.ValueOf(method).Pointer()).Name()) {
                        calls = append(calls, call)
index be29bc23ef394df21ac95a19ea169873d83af4ca..10b95c037116da0dc75f01b643a0d9fb587d4c46 100644 (file)
@@ -13,6 +13,7 @@ const (
        AdminToken              = "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h"
        AnonymousToken          = "4kg6k6lzmp9kj4cpkcoxie964cmvjahbt4fod9zru44k4jqdmi"
        DataManagerToken        = "320mkve8qkswstz7ff61glpk3mhgghmg67wmic7elw4z41pke1"
+       SystemRootToken         = "systemusertesttoken1234567890aoeuidhtnsqjkxbmwvzpy"
        ManagementToken         = "jg3ajndnq63sywcd50gbs5dskdc9ckkysb0nsqmfz08nwf17nl"
        ActiveUserUUID          = "zzzzz-tpzed-xurymjxw79nv3jz"
        FederatedActiveUserUUID = "zbbbb-tpzed-xurymjxw79nv3jz"
index 48aabbbe409a5c672d7917ae8b57b73973fd7bec..dd74df2367812d48272e6be28827e7e0b806c398 100644 (file)
@@ -719,7 +719,7 @@ def setup_config():
             "zzzzz": {
                 "EnableBetaController14287": ('14287' in os.environ.get('ARVADOS_EXPERIMENTAL', '')),
                 "ManagementToken": "e687950a23c3a9bceec28c6223a06c79",
-                "SystemRootToken": auth_token('data_manager'),
+                "SystemRootToken": auth_token('system_user'),
                 "API": {
                     "RequestTimeout": "30s",
                 },
index 5b0dc123ae49a627a98c4f5254ff6a1649e869e6..43816a213b157c2f293f6d54bc0812005b227a28 100644 (file)
@@ -39,7 +39,7 @@ func (s *integrationSuite) SetUpSuite(c *check.C) {
        arvadostest.StartKeep(4, true)
 
        arv, err := arvadosclient.MakeArvadosClient()
-       arv.ApiToken = arvadostest.DataManagerToken
+       arv.ApiToken = arvadostest.SystemRootToken
        c.Assert(err, check.IsNil)
 
        s.keepClient, err = keepclient.MakeKeepClient(arv)
@@ -71,7 +71,7 @@ func (s *integrationSuite) SetUpTest(c *check.C) {
 
        s.client = &arvados.Client{
                APIHost:   os.Getenv("ARVADOS_API_HOST"),
-               AuthToken: arvadostest.DataManagerToken,
+               AuthToken: arvadostest.SystemRootToken,
                Insecure:  true,
        }
 }
index 54b4871fab89a59a2b95ba893912080ec13ff070..8247ce480dd37abe96f8f2c7514745ac517c8e34 100644 (file)
@@ -46,7 +46,7 @@ func testCluster(t TB) *arvados.Cluster {
        if err != nil {
                t.Fatal(err)
        }
-       cluster.SystemRootToken = arvadostest.DataManagerToken
+       cluster.SystemRootToken = arvadostest.SystemRootToken
        cluster.ManagementToken = arvadostest.ManagementToken
        cluster.Collections.BlobSigning = false
        return cluster
index dd6247f8bb2824879669f6bb7d9c21eae2d61df2..30193415353b2abf2723a91a672810bdd4b82a8d 100644 (file)
@@ -55,7 +55,7 @@ func (s *HandlerSuite) TestMounts(c *check.C) {
                c.Check(resp.Body.String(), check.Equals, "Unauthorized\n")
        }
 
-       tok := arvadostest.DataManagerToken
+       tok := arvadostest.SystemRootToken
 
        // Nonexistent mount UUID
        resp = s.call("GET", "/mounts/X/blocks", tok, nil)
index 6483d6cf01310af98d78b5fd1074b3301004bd83..fd98aa9cb01d605cc12eaf91619f53e44a0edb65 100644 (file)
@@ -89,7 +89,7 @@ func (s *ProxyRemoteSuite) SetUpTest(c *check.C) {
        s.remoteAPI.StartTLS()
        s.cluster = testCluster(c)
        s.cluster.Collections.BlobSigningKey = knownKey
-       s.cluster.SystemRootToken = arvadostest.DataManagerToken
+       s.cluster.SystemRootToken = arvadostest.SystemRootToken
        s.cluster.RemoteClusters = map[string]arvados.RemoteCluster{
                s.remoteClusterID: arvados.RemoteCluster{
                        Host:     strings.Split(s.remoteAPI.URL, "//")[1],
index 9c37e38906f0ebd59562c47a50f53dd67f0bdb78..22979dc98fbd0b2c83625bdb89745fa65343fbac 100644 (file)
@@ -89,13 +89,13 @@ func setupRsync(c *C, enforcePermissions bool, replications int) {
        // srcConfig
        var srcConfig apiConfig
        srcConfig.APIHost = os.Getenv("ARVADOS_API_HOST")
-       srcConfig.APIToken = arvadostest.DataManagerToken
+       srcConfig.APIToken = arvadostest.SystemRootToken
        srcConfig.APIHostInsecure = arvadosclient.StringBool(os.Getenv("ARVADOS_API_HOST_INSECURE"))
 
        // dstConfig
        var dstConfig apiConfig
        dstConfig.APIHost = os.Getenv("ARVADOS_API_HOST")
-       dstConfig.APIToken = arvadostest.DataManagerToken
+       dstConfig.APIToken = arvadostest.SystemRootToken
        dstConfig.APIHostInsecure = arvadosclient.StringBool(os.Getenv("ARVADOS_API_HOST_INSECURE"))
 
        if enforcePermissions {
@@ -370,7 +370,7 @@ func (s *ServerNotRequiredSuite) TestLoadConfig(c *C) {
        c.Check(err, IsNil)
 
        c.Assert(srcConfig.APIHost, Equals, os.Getenv("ARVADOS_API_HOST"))
-       c.Assert(srcConfig.APIToken, Equals, arvadostest.DataManagerToken)
+       c.Assert(srcConfig.APIToken, Equals, arvadostest.SystemRootToken)
        c.Assert(srcConfig.APIHostInsecure, Equals, arvadosclient.StringBool(os.Getenv("ARVADOS_API_HOST_INSECURE")))
        c.Assert(srcConfig.ExternalClient, Equals, false)
 
@@ -378,7 +378,7 @@ func (s *ServerNotRequiredSuite) TestLoadConfig(c *C) {
        c.Check(err, IsNil)
 
        c.Assert(dstConfig.APIHost, Equals, os.Getenv("ARVADOS_API_HOST"))
-       c.Assert(dstConfig.APIToken, Equals, arvadostest.DataManagerToken)
+       c.Assert(dstConfig.APIToken, Equals, arvadostest.SystemRootToken)
        c.Assert(dstConfig.APIHostInsecure, Equals, arvadosclient.StringBool(os.Getenv("ARVADOS_API_HOST_INSECURE")))
        c.Assert(dstConfig.ExternalClient, Equals, false)
 
@@ -401,7 +401,7 @@ func (s *ServerNotRequiredSuite) TestLoadConfig_ErrorLoadingSrcConfig(c *C) {
 func (s *ServerNotRequiredSuite) TestSetupKeepClient_NoBlobSignatureTTL(c *C) {
        var srcConfig apiConfig
        srcConfig.APIHost = os.Getenv("ARVADOS_API_HOST")
-       srcConfig.APIToken = arvadostest.DataManagerToken
+       srcConfig.APIToken = arvadostest.SystemRootToken
        srcConfig.APIHostInsecure = arvadosclient.StringBool(os.Getenv("ARVADOS_API_HOST_INSECURE"))
 
        _, ttl, err := setupKeepClient(srcConfig, srcKeepServicesJSON, false, 0, 0)
@@ -415,7 +415,7 @@ func setupConfigFile(c *C, name string) *os.File {
        c.Check(err, IsNil)
 
        fileContent := "ARVADOS_API_HOST=" + os.Getenv("ARVADOS_API_HOST") + "\n"
-       fileContent += "ARVADOS_API_TOKEN=" + arvadostest.DataManagerToken + "\n"
+       fileContent += "ARVADOS_API_TOKEN=" + arvadostest.SystemRootToken + "\n"
        fileContent += "ARVADOS_API_HOST_INSECURE=" + os.Getenv("ARVADOS_API_HOST_INSECURE") + "\n"
        fileContent += "ARVADOS_EXTERNAL_CLIENT=false\n"
        fileContent += "ARVADOS_BLOB_SIGNING_KEY=abcdefg"