21703: Fix unlogged exception.
[arvados.git] / services / api / test / functional / sys_controller_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6
7 class SysControllerTest < ActionController::TestCase
8   include CurrentApiClient
9   include DbCurrentTime
10
11   test "trash_sweep - delete expired tokens" do
12     assert_not_empty ApiClientAuthorization.where(uuid: api_client_authorizations(:expired).uuid)
13     authorize_with :admin
14     post :trash_sweep
15     assert_response :success
16     assert_empty ApiClientAuthorization.where(uuid: api_client_authorizations(:expired).uuid)
17   end
18
19   test "trash_sweep - fail with non-admin token" do
20     authorize_with :active
21     post :trash_sweep
22     assert_response 403
23   end
24
25   test "trash_sweep - move collections to trash" do
26     c = collections(:trashed_on_next_sweep)
27     refute_empty Collection.where('uuid=? and is_trashed=false', c.uuid)
28     assert_raises(ActiveRecord::RecordNotUnique) do
29       act_as_user users(:active) do
30         Collection.create!(owner_uuid: c.owner_uuid,
31                            name: c.name)
32       end
33     end
34     authorize_with :admin
35     post :trash_sweep
36     assert_response :success
37     c = Collection.where('uuid=? and is_trashed=true', c.uuid).first
38     assert c
39     act_as_user users(:active) do
40       assert Collection.create!(owner_uuid: c.owner_uuid,
41                                 name: c.name)
42     end
43   end
44
45   test "trash_sweep - delete collections" do
46     uuid = 'zzzzz-4zz18-3u1p5umicfpqszp' # deleted_on_next_sweep
47     assert_not_empty Collection.where(uuid: uuid)
48     authorize_with :admin
49     post :trash_sweep
50     assert_response :success
51     assert_empty Collection.where(uuid: uuid)
52   end
53
54   test "trash_sweep - delete referring links" do
55     uuid = collections(:trashed_on_next_sweep).uuid
56     act_as_system_user do
57       assert_raises ActiveRecord::RecordInvalid do
58         # Cannot create because :trashed_on_next_sweep is already trashed
59         Link.create!(head_uuid: uuid,
60                      tail_uuid: system_user_uuid,
61                      link_class: 'whatever',
62                      name: 'something')
63       end
64
65       # Bump trash_at to now + 1 minute
66       Collection.where(uuid: uuid).
67         update(trash_at: db_current_time + (1).minute)
68
69       # Not considered trashed now
70       Link.create!(head_uuid: uuid,
71                    tail_uuid: system_user_uuid,
72                    link_class: 'whatever',
73                    name: 'something')
74     end
75     past = db_current_time
76     Collection.where(uuid: uuid).
77       update_all(is_trashed: true, trash_at: past, delete_at: past)
78     assert_not_empty Collection.where(uuid: uuid)
79     authorize_with :admin
80     post :trash_sweep
81     assert_response :success
82     assert_empty Collection.where(uuid: uuid)
83   end
84
85   test "trash_sweep - move projects to trash" do
86     p = groups(:trashed_on_next_sweep)
87     assert_empty Group.where('uuid=? and is_trashed=true', p.uuid)
88     authorize_with :admin
89     post :trash_sweep
90     assert_response :success
91     assert_not_empty Group.where('uuid=? and is_trashed=true', p.uuid)
92   end
93
94   test "trash_sweep - role groups are deleted" do
95     p = groups(:trashed_role_on_next_sweep)
96     assert_empty Group.where('uuid=? and is_trashed=true', p.uuid)
97     assert_not_empty Link.where(uuid: links(:foo_file_readable_by_soon_to_be_trashed_role).uuid)
98     authorize_with :admin
99     post :trash_sweep
100     assert_response :success
101     assert_empty Group.where(uuid: p.uuid)
102     assert_empty Link.where(uuid: links(:foo_file_readable_by_soon_to_be_trashed_role).uuid)
103   end
104
105   test "trash_sweep - delete projects and their contents" do
106     g_foo = groups(:trashed_project)
107     g_bar = groups(:trashed_subproject)
108     g_baz = groups(:trashed_subproject3)
109     col = collections(:collection_in_trashed_subproject)
110     cr = container_requests(:cr_in_trashed_project)
111     # Save how many objects were before the sweep
112     user_nr_was = User.all.length
113     coll_nr_was = Collection.all.length
114     group_nr_was = Group.where('group_class<>?', 'project').length
115     project_nr_was = Group.where(group_class: 'project').length
116     cr_nr_was = ContainerRequest.all.length
117     assert_not_empty Group.where(uuid: g_foo.uuid)
118     assert_not_empty Group.where(uuid: g_bar.uuid)
119     assert_not_empty Group.where(uuid: g_baz.uuid)
120     assert_not_empty Collection.where(uuid: col.uuid)
121     assert_not_empty ContainerRequest.where(uuid: cr.uuid)
122
123     authorize_with :admin
124     Group.find_by_uuid(g_foo.uuid).update!(delete_at: Time.now - 1.second)
125
126     post :trash_sweep
127     assert_response :success
128
129     assert_empty Group.where(uuid: g_foo.uuid)
130     assert_empty Group.where(uuid: g_bar.uuid)
131     assert_empty Group.where(uuid: g_baz.uuid)
132     assert_empty Collection.where(uuid: col.uuid)
133     assert_empty ContainerRequest.where(uuid: cr.uuid)
134     # No unwanted deletions should have happened
135     assert_equal user_nr_was, User.all.length
136     assert_equal coll_nr_was-2,        # collection_in_trashed_subproject
137                  Collection.all.length # & deleted_on_next_sweep collections
138     assert_equal group_nr_was-1,       # trashed_role_on_next_sweep
139                  Group.where('group_class<>?', 'project').length
140     assert_equal project_nr_was-3, Group.where(group_class: 'project').length
141     assert_equal cr_nr_was-1, ContainerRequest.all.length
142   end
143
144   test "trash_sweep - delete unused uuid_locks" do
145     uuid_active = "zzzzz-zzzzz-uuidlockstest11"
146     uuid_inactive = "zzzzz-zzzzz-uuidlockstest00"
147
148     ready = Queue.new
149     insertsql = "INSERT INTO uuid_locks (uuid) VALUES ($1) ON CONFLICT (uuid) do UPDATE SET n = uuid_locks.n+1"
150     url = ENV["DATABASE_URL"].sub(/\?.*/, '')
151     Thread.new do
152       conn = PG::Connection.new(url)
153       conn.exec_params(insertsql, [uuid_active])
154       conn.exec_params(insertsql, [uuid_inactive])
155       conn.transaction do |conn|
156         conn.exec_params(insertsql, [uuid_active])
157         ready << true
158         # If we keep this transaction open while trash_sweep runs, the
159         # uuid_active row shouldn't get deleted.
160         sleep 10
161       rescue
162         # Unblock main thread
163         ready << false
164         raise
165       end
166     end
167     assert_equal true, ready.pop
168     authorize_with :admin
169     post :trash_sweep
170     assert_equal [[uuid_active]], ActiveRecord::Base.connection.exec_query("SELECT uuid FROM uuid_locks ORDER BY uuid", "", []).rows
171   end
172 end