13497: Add timeout for proxy requests.
[arvados.git] / lib / controller / handler_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package controller
6
7 import (
8         "encoding/json"
9         "net/http"
10         "net/http/httptest"
11         "os"
12         "testing"
13         "time"
14
15         "git.curoverse.com/arvados.git/sdk/go/arvados"
16         "git.curoverse.com/arvados.git/sdk/go/arvadostest"
17         "git.curoverse.com/arvados.git/sdk/go/httpserver"
18         check "gopkg.in/check.v1"
19 )
20
21 // Gocheck boilerplate
22 func Test(t *testing.T) {
23         check.TestingT(t)
24 }
25
26 var _ = check.Suite(&HandlerSuite{})
27
28 type HandlerSuite struct {
29         cluster *arvados.Cluster
30         handler http.Handler
31 }
32
33 func (s *HandlerSuite) SetUpTest(c *check.C) {
34         s.cluster = &arvados.Cluster{
35                 ClusterID: "zzzzz",
36                 SystemNodes: map[string]arvados.SystemNode{
37                         "*": {
38                                 Controller: arvados.SystemServiceInstance{Listen: ":"},
39                                 RailsAPI:   arvados.SystemServiceInstance{Listen: os.Getenv("ARVADOS_API_HOST"), TLS: true},
40                         },
41                 },
42         }
43         node := s.cluster.SystemNodes["*"]
44         s.handler = newHandler(s.cluster, &node)
45 }
46
47 func (s *HandlerSuite) TestProxyDiscoveryDoc(c *check.C) {
48         req := httptest.NewRequest("GET", "/discovery/v1/apis/arvados/v1/rest", nil)
49         resp := httptest.NewRecorder()
50         s.handler.ServeHTTP(resp, req)
51         c.Check(resp.Code, check.Equals, http.StatusOK)
52         var dd arvados.DiscoveryDocument
53         err := json.Unmarshal(resp.Body.Bytes(), &dd)
54         c.Check(err, check.IsNil)
55         c.Check(dd.BlobSignatureTTL, check.Not(check.Equals), int64(0))
56         c.Check(dd.BlobSignatureTTL > 0, check.Equals, true)
57         c.Check(len(dd.Resources), check.Not(check.Equals), 0)
58         c.Check(len(dd.Schemas), check.Not(check.Equals), 0)
59 }
60
61 func (s *HandlerSuite) TestRequestTimeout(c *check.C) {
62         s.cluster.HTTPRequestTimeout = arvados.Duration(time.Nanosecond)
63         req := httptest.NewRequest("GET", "/discovery/v1/apis/arvados/v1/rest", nil)
64         resp := httptest.NewRecorder()
65         s.handler.ServeHTTP(resp, req)
66         c.Check(resp.Code, check.Equals, http.StatusInternalServerError)
67         var jresp httpserver.ErrorResponse
68         err := json.Unmarshal(resp.Body.Bytes(), &jresp)
69         c.Check(err, check.IsNil)
70         c.Assert(len(jresp.Errors), check.Equals, 1)
71         c.Check(jresp.Errors[0], check.Matches, `.*context deadline exceeded`)
72 }
73
74 func (s *HandlerSuite) TestProxyWithoutToken(c *check.C) {
75         req := httptest.NewRequest("GET", "/arvados/v1/users/current", nil)
76         resp := httptest.NewRecorder()
77         s.handler.ServeHTTP(resp, req)
78         c.Check(resp.Code, check.Equals, http.StatusUnauthorized)
79         jresp := map[string]interface{}{}
80         err := json.Unmarshal(resp.Body.Bytes(), &jresp)
81         c.Check(err, check.IsNil)
82         c.Check(jresp["errors"], check.FitsTypeOf, []interface{}{})
83 }
84
85 func (s *HandlerSuite) TestProxyWithToken(c *check.C) {
86         req := httptest.NewRequest("GET", "/arvados/v1/users/current", nil)
87         req.Header.Set("Authorization", "Bearer "+arvadostest.ActiveToken)
88         resp := httptest.NewRecorder()
89         s.handler.ServeHTTP(resp, req)
90         c.Check(resp.Code, check.Equals, http.StatusOK)
91         var u arvados.User
92         err := json.Unmarshal(resp.Body.Bytes(), &u)
93         c.Check(err, check.IsNil)
94         c.Check(u.UUID, check.Equals, arvadostest.ActiveUserUUID)
95 }
96
97 func (s *HandlerSuite) TestProxyNotFound(c *check.C) {
98         req := httptest.NewRequest("GET", "/arvados/v1/xyzzy", nil)
99         resp := httptest.NewRecorder()
100         s.handler.ServeHTTP(resp, req)
101         c.Check(resp.Code, check.Equals, http.StatusNotFound)
102         jresp := map[string]interface{}{}
103         err := json.Unmarshal(resp.Body.Bytes(), &jresp)
104         c.Check(err, check.IsNil)
105         c.Check(jresp["errors"], check.FitsTypeOf, []interface{}{})
106 }