Merge branch 'main' into 22155-layout-bugs
[arvados.git] / lib / controller / federation / collection_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package federation
6
7 import (
8         "context"
9         "fmt"
10         "net/http"
11
12         "git.arvados.org/arvados.git/lib/ctrlctx"
13         "git.arvados.org/arvados.git/sdk/go/arvados"
14         "git.arvados.org/arvados.git/sdk/go/arvadostest"
15         "git.arvados.org/arvados.git/sdk/go/auth"
16         "git.arvados.org/arvados.git/sdk/go/ctxlog"
17         "git.arvados.org/arvados.git/sdk/go/httpserver"
18         check "gopkg.in/check.v1"
19 )
20
21 var _ = check.Suite(&collectionSuite{})
22
23 type collectionSuite struct {
24         FederationSuite
25 }
26
27 func (s *collectionSuite) TestMultipleBackendFailureStatus(c *check.C) {
28         nxPDH := "a4f995dd0c08216f37cb1bdec990f0cd+1234"
29         s.cluster.ClusterID = "local"
30         for _, trial := range []struct {
31                 label        string
32                 token        string
33                 localStatus  int
34                 remoteStatus map[string]int
35                 expectStatus int
36         }{
37                 {
38                         "all backends return 404 => 404",
39                         arvadostest.SystemRootToken,
40                         http.StatusNotFound,
41                         map[string]int{
42                                 "aaaaa": http.StatusNotFound,
43                                 "bbbbb": http.StatusNotFound,
44                         },
45                         http.StatusNotFound,
46                 },
47                 {
48                         "all backends return 401 => 401 (e.g., bad token)",
49                         arvadostest.SystemRootToken,
50                         http.StatusUnauthorized,
51                         map[string]int{
52                                 "aaaaa": http.StatusUnauthorized,
53                                 "bbbbb": http.StatusUnauthorized,
54                         },
55                         http.StatusUnauthorized,
56                 },
57                 {
58                         "local 404, remotes 403 => 422 (mix of non-retryable errors)",
59                         arvadostest.SystemRootToken,
60                         http.StatusNotFound,
61                         map[string]int{
62                                 "aaaaa": http.StatusForbidden,
63                                 "bbbbb": http.StatusForbidden,
64                         },
65                         http.StatusUnprocessableEntity,
66                 },
67                 {
68                         "local 404, remotes 401/403/404 => 422 (mix of non-retryable errors)",
69                         arvadostest.SystemRootToken,
70                         http.StatusNotFound,
71                         map[string]int{
72                                 "aaaaa": http.StatusUnauthorized,
73                                 "bbbbb": http.StatusForbidden,
74                                 "ccccc": http.StatusNotFound,
75                         },
76                         http.StatusUnprocessableEntity,
77                 },
78                 {
79                         "local 404, remotes 401/403/500 => 502 (at least one remote is retryable)",
80                         arvadostest.SystemRootToken,
81                         http.StatusNotFound,
82                         map[string]int{
83                                 "aaaaa": http.StatusUnauthorized,
84                                 "bbbbb": http.StatusForbidden,
85                                 "ccccc": http.StatusInternalServerError,
86                         },
87                         http.StatusBadGateway,
88                 },
89         } {
90                 c.Logf("trial: %v", trial)
91                 s.fed = New(s.ctx, s.cluster, nil, (&ctrlctx.DBConnector{PostgreSQL: s.cluster.PostgreSQL}).GetDB)
92                 s.fed.local = &arvadostest.APIStub{Error: httpserver.ErrorWithStatus(fmt.Errorf("stub error %d", trial.localStatus), trial.localStatus)}
93                 for id, status := range trial.remoteStatus {
94                         s.addDirectRemote(c, id, &arvadostest.APIStub{Error: httpserver.ErrorWithStatus(fmt.Errorf("stub error %d", status), status)})
95                 }
96
97                 ctx := context.Background()
98                 ctx = ctxlog.Context(ctx, ctxlog.TestLogger(c))
99                 if trial.token != "" {
100                         ctx = auth.NewContext(ctx, &auth.Credentials{Tokens: []string{trial.token}})
101                 }
102
103                 _, err := s.fed.CollectionGet(s.ctx, arvados.GetOptions{UUID: nxPDH})
104                 c.Check(err.(httpserver.HTTPStatusError).HTTPStatus(), check.Equals, trial.expectStatus)
105         }
106 }