13558: add req_id as a tag to Rails.logger
[arvados.git] / services / api / test / unit / collection_test.rb
index 87bec21520a05b27c76e807555ba84b45739500d..8b8c48fe1c865f23e73bdf2c00befbb27031724a 100644 (file)
@@ -1,5 +1,9 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'test_helper'
-require 'sweep_trashed_collections'
+require 'sweep_trashed_objects'
 
 class CollectionTest < ActiveSupport::TestCase
   include DbCurrentTime
@@ -217,6 +221,81 @@ class CollectionTest < ActiveSupport::TestCase
     end
   end
 
+  test "storage_classes_desired cannot be empty" do
+    act_as_user users(:active) do
+      c = collections(:collection_owned_by_active)
+      c.update_attributes storage_classes_desired: ["hot"]
+      assert_equal ["hot"], c.storage_classes_desired
+      assert_raise ArvadosModel::InvalidStateTransitionError do
+        c.update_attributes storage_classes_desired: []
+      end
+    end
+  end
+
+  test "storage classes lists should only contain non-empty strings" do
+    c = collections(:storage_classes_desired_default_unconfirmed)
+    act_as_user users(:admin) do
+      assert c.update_attributes(storage_classes_desired: ["default", "a_string"],
+                                 storage_classes_confirmed: ["another_string"])
+      [
+        ["storage_classes_desired", ["default", 42]],
+        ["storage_classes_confirmed", [{the_answer: 42}]],
+        ["storage_classes_desired", ["default", ""]],
+        ["storage_classes_confirmed", [""]],
+      ].each do |attr, val|
+        assert_raise ArvadosModel::InvalidStateTransitionError do
+          assert c.update_attributes({attr => val})
+        end
+      end
+    end
+  end
+
+  test "storage_classes_confirmed* can be set by admin user" do
+    c = collections(:storage_classes_desired_default_unconfirmed)
+    act_as_user users(:admin) do
+      assert c.update_attributes(storage_classes_confirmed: ["default"],
+                                 storage_classes_confirmed_at: Time.now)
+    end
+  end
+
+  test "storage_classes_confirmed* cannot be set by non-admin user" do
+    act_as_user users(:active) do
+      c = collections(:storage_classes_desired_default_unconfirmed)
+      # Cannot set just one at a time.
+      assert_raise ArvadosModel::PermissionDeniedError do
+        c.update_attributes storage_classes_confirmed: ["default"]
+      end
+      c.reload
+      assert_raise ArvadosModel::PermissionDeniedError do
+        c.update_attributes storage_classes_confirmed_at: Time.now
+      end
+      # Cannot set bot at once, either.
+      c.reload
+      assert_raise ArvadosModel::PermissionDeniedError do
+        assert c.update_attributes(storage_classes_confirmed: ["default"],
+                                   storage_classes_confirmed_at: Time.now)
+      end
+    end
+  end
+
+  test "storage_classes_confirmed* can be cleared (but only together) by non-admin user" do
+    act_as_user users(:active) do
+      c = collections(:storage_classes_desired_default_confirmed_default)
+      # Cannot clear just one at a time.
+      assert_raise ArvadosModel::PermissionDeniedError do
+        c.update_attributes storage_classes_confirmed: []
+      end
+      c.reload
+      assert_raise ArvadosModel::PermissionDeniedError do
+        c.update_attributes storage_classes_confirmed_at: nil
+      end
+      # Can clear both at once.
+      c.reload
+      assert c.update_attributes(storage_classes_confirmed: [],
+                                 storage_classes_confirmed_at: nil)
+    end
+  end
+
   [0, 2, 4, nil].each do |ask|
     test "set replication_desired to #{ask.inspect}" do
       Rails.configuration.default_collection_replication = 2
@@ -348,9 +427,12 @@ class CollectionTest < ActiveSupport::TestCase
       assert c.valid?
       uuid = c.uuid
 
+      c = Collection.readable_by(current_user).where(uuid: uuid)
+      assert_not_empty c, 'Should be able to find live collection'
+
       # mark collection as expired
-      c.update_attributes!(trash_at: Time.new.strftime("%Y-%m-%d"))
-      c = Collection.where(uuid: uuid)
+      c.first.update_attributes!(trash_at: Time.new.strftime("%Y-%m-%d"))
+      c = Collection.readable_by(current_user).where(uuid: uuid)
       assert_empty c, 'Should not be able to find expired collection'
 
       # recreate collection with the same name
@@ -370,21 +452,26 @@ class CollectionTest < ActiveSupport::TestCase
     end
   end
 
+  now = Time.now
   [['trash-to-delete interval negative',
     :collection_owned_by_active,
-    {trash_at: Time.now+2.weeks, delete_at: Time.now},
+    {trash_at: now+2.weeks, delete_at: now},
     {state: :invalid}],
-   ['trash-to-delete interval too short',
+   ['now-to-delete interval short',
     :collection_owned_by_active,
-    {trash_at: Time.now+3.days, delete_at: Time.now+7.days},
-    {state: :invalid}],
+    {trash_at: now+3.days, delete_at: now+7.days},
+    {state: :trash_future}],
+   ['now-to-delete interval short, trash=delete',
+    :collection_owned_by_active,
+    {trash_at: now+3.days, delete_at: now+3.days},
+    {state: :trash_future}],
    ['trash-to-delete interval ok',
     :collection_owned_by_active,
-    {trash_at: Time.now, delete_at: Time.now+15.days},
+    {trash_at: now, delete_at: now+15.days},
     {state: :trash_now}],
    ['trash-to-delete interval short, but far enough in future',
     :collection_owned_by_active,
-    {trash_at: Time.now+13.days, delete_at: Time.now+15.days},
+    {trash_at: now+13.days, delete_at: now+15.days},
     {state: :trash_future}],
    ['trash by setting is_trashed bool',
     :collection_owned_by_active,
@@ -392,11 +479,11 @@ class CollectionTest < ActiveSupport::TestCase
     {state: :trash_now}],
    ['trash in future by setting just trash_at',
     :collection_owned_by_active,
-    {trash_at: Time.now+1.week},
+    {trash_at: now+1.week},
     {state: :trash_future}],
    ['trash in future by setting trash_at and delete_at',
     :collection_owned_by_active,
-    {trash_at: Time.now+1.week, delete_at: Time.now+4.weeks},
+    {trash_at: now+1.week, delete_at: now+4.weeks},
     {state: :trash_future}],
    ['untrash by clearing is_trashed bool',
     :expired_collection,
@@ -410,13 +497,13 @@ class CollectionTest < ActiveSupport::TestCase
         if fixture_name == :expired_collection
           # Fixture-finder shorthand doesn't find trashed collections
           # because they're not in the default scope.
-          c = Collection.unscoped.find_by_uuid('zzzzz-4zz18-mto52zx1s7sn3ih')
+          c = Collection.find_by_uuid('zzzzz-4zz18-mto52zx1s7sn3ih')
         else
           c = collections(fixture_name)
         end
         updates_ok = c.update_attributes(updates)
         expect_valid = expect[:state] != :invalid
-        assert_equal updates_ok, expect_valid, c.errors.full_messages.to_s
+        assert_equal expect_valid, updates_ok, c.errors.full_messages.to_s
         case expect[:state]
         when :invalid
           refute c.valid?
@@ -469,7 +556,7 @@ class CollectionTest < ActiveSupport::TestCase
     assert_includes(coll_uuids, collections(:docker_image).uuid)
   end
 
-  test "move to trash in SweepTrashedCollections" do
+  test "move collections to trash in SweepTrashedObjects" do
     c = collections(:trashed_on_next_sweep)
     refute_empty Collection.where('uuid=? and is_trashed=false', c.uuid)
     assert_raises(ActiveRecord::RecordNotUnique) do
@@ -478,8 +565,8 @@ class CollectionTest < ActiveSupport::TestCase
                            name: c.name)
       end
     end
-    SweepTrashedCollections.sweep_now
-    c = Collection.unscoped.where('uuid=? and is_trashed=true', c.uuid).first
+    SweepTrashedObjects.sweep_now
+    c = Collection.where('uuid=? and is_trashed=true', c.uuid).first
     assert c
     act_as_user users(:active) do
       assert Collection.create!(owner_uuid: c.owner_uuid,
@@ -487,14 +574,14 @@ class CollectionTest < ActiveSupport::TestCase
     end
   end
 
-  test "delete in SweepTrashedCollections" do
+  test "delete collections in SweepTrashedObjects" do
     uuid = 'zzzzz-4zz18-3u1p5umicfpqszp' # deleted_on_next_sweep
-    assert_not_empty Collection.unscoped.where(uuid: uuid)
-    SweepTrashedCollections.sweep_now
-    assert_empty Collection.unscoped.where(uuid: uuid)
+    assert_not_empty Collection.where(uuid: uuid)
+    SweepTrashedObjects.sweep_now
+    assert_empty Collection.where(uuid: uuid)
   end
 
-  test "delete referring links in SweepTrashedCollections" do
+  test "delete referring links in SweepTrashedObjects" do
     uuid = collections(:trashed_on_next_sweep).uuid
     act_as_system_user do
       Link.create!(head_uuid: uuid,
@@ -503,10 +590,10 @@ class CollectionTest < ActiveSupport::TestCase
                    name: 'something')
     end
     past = db_current_time
-    Collection.unscoped.where(uuid: uuid).
+    Collection.where(uuid: uuid).
       update_all(is_trashed: true, trash_at: past, delete_at: past)
-    assert_not_empty Collection.unscoped.where(uuid: uuid)
-    SweepTrashedCollections.sweep_now
-    assert_empty Collection.unscoped.where(uuid: uuid)
+    assert_not_empty Collection.where(uuid: uuid)
+    SweepTrashedObjects.sweep_now
+    assert_empty Collection.where(uuid: uuid)
   end
 end