X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/9b61792d905324a98b24224d45347082efbe5205..eae48c31bb338689ec67fbc6a14a2e0b1fb5e3b6:/services/api/test/functional/arvados/v1/collections_controller_test.rb diff --git a/services/api/test/functional/arvados/v1/collections_controller_test.rb b/services/api/test/functional/arvados/v1/collections_controller_test.rb index 61b0557085..c85cc1979f 100644 --- a/services/api/test/functional/arvados/v1/collections_controller_test.rb +++ b/services/api/test/functional/arvados/v1/collections_controller_test.rb @@ -46,6 +46,49 @@ class Arvados::V1::CollectionsControllerTest < ActionController::TestCase end end + test 'index without select returns everything except manifest' do + authorize_with :active + get :index + assert_response :success + assert json_response['items'].any? + json_response['items'].each do |coll| + assert_includes(coll.keys, 'uuid') + assert_includes(coll.keys, 'name') + assert_includes(coll.keys, 'created_at') + refute_includes(coll.keys, 'manifest_text') + end + end + + ['', nil, false, 'null'].each do |select| + test "index with select=#{select.inspect} returns everything except manifest" do + authorize_with :active + get :index, select: select + assert_response :success + assert json_response['items'].any? + json_response['items'].each do |coll| + assert_includes(coll.keys, 'uuid') + assert_includes(coll.keys, 'name') + assert_includes(coll.keys, 'created_at') + refute_includes(coll.keys, 'manifest_text') + end + end + end + + [["uuid"], + ["uuid", "manifest_text"], + '["uuid"]', + '["uuid", "manifest_text"]'].each do |select| + test "index with select=#{select.inspect} returns no name" do + authorize_with :active + get :index, select: select + assert_response :success + assert json_response['items'].any? + json_response['items'].each do |coll| + refute_includes(coll.keys, 'name') + end + end + end + [0,1,2].each do |limit| test "get index with limit=#{limit}" do authorize_with :active @@ -91,6 +134,71 @@ class Arvados::V1::CollectionsControllerTest < ActionController::TestCase assert_equal 99999, resp['offset'] end + def request_capped_index(params={}) + authorize_with :user1_with_load + coll1 = collections(:collection_1_of_201) + Rails.configuration.max_index_database_read = + yield(coll1.manifest_text.size) + get :index, { + select: %w(uuid manifest_text), + filters: [["owner_uuid", "=", coll1.owner_uuid]], + limit: 300, + }.merge(params) + end + + test "index with manifest_text limited by max_index_database_read returns non-empty" do + request_capped_index() { |_| 1 } + assert_response :success + assert_equal(1, json_response["items"].size) + assert_equal(1, json_response["limit"]) + assert_equal(201, json_response["items_available"]) + end + + test "max_index_database_read size check follows same order as real query" do + authorize_with :user1_with_load + txt = '.' + ' d41d8cd98f00b204e9800998ecf8427e+0'*1000 + " 0:0:empty.txt\n" + c = Collection.create! manifest_text: txt, name: '0000000000000000000' + request_capped_index(select: %w(uuid manifest_text name), + order: ['name asc'], + filters: [['name','>=',c.name]]) do |_| + txt.length - 1 + end + assert_response :success + assert_equal(1, json_response["items"].size) + assert_equal(1, json_response["limit"]) + assert_equal(c.uuid, json_response["items"][0]["uuid"]) + # The effectiveness of the test depends on >1 item matching the filters. + assert_operator(1, :<, json_response["items_available"]) + end + + test "index with manifest_text limited by max_index_database_read" do + request_capped_index() { |size| (size * 3) + 1 } + assert_response :success + assert_equal(3, json_response["items"].size) + assert_equal(3, json_response["limit"]) + assert_equal(201, json_response["items_available"]) + end + + test "max_index_database_read does not interfere with limit" do + request_capped_index(limit: 5) { |size| size * 20 } + assert_response :success + assert_equal(5, json_response["items"].size) + assert_equal(5, json_response["limit"]) + assert_equal(201, json_response["items_available"]) + end + + test "max_index_database_read does not interfere with order" do + request_capped_index(select: %w(uuid manifest_text name), + order: "name DESC") { |size| (size * 11) + 1 } + assert_response :success + assert_equal(11, json_response["items"].size) + assert_empty(json_response["items"].reject do |coll| + coll["name"] =~ /^Collection_9/ + end) + assert_equal(11, json_response["limit"]) + assert_equal(201, json_response["items_available"]) + end + test "admin can create collection with unsigned manifest" do authorize_with :admin test_collection = { @@ -466,8 +574,8 @@ EOS } # Generate a locator with a bad signature. - unsigned_locator = "d41d8cd98f00b204e9800998ecf8427e+0" - bad_locator = unsigned_locator + "+Affffffff@ffffffff" + unsigned_locator = "acbd18db4cc2f85cedef654fccc4a4d8+3" + bad_locator = unsigned_locator + "+Affffffffffffffffffffffffffffffffffffffff@ffffffff" assert !Blob.verify_signature(bad_locator, signing_opts) # Creating a collection with this locator should @@ -512,6 +620,16 @@ EOS assert_response 422 end + test "reject manifest with unsigned block as stream name" do + authorize_with :active + post :create, { + collection: { + manifest_text: "00000000000000000000000000000000+1234 d41d8cd98f00b204e9800998ecf8427e+0 0:0:foo.txt\n" + } + } + assert_includes [422, 403], response.code.to_i + end + test "multiple locators per line" do permit_unsigned_manifests authorize_with :active @@ -698,21 +816,118 @@ EOS end [1, 5, nil].each do |ask| - test "Set replication_desired=#{ask} using redundancy attr" do - # The Python SDK checks the Collection schema in the discovery - # doc, then asks for 'redundancy' or 'replication_desired' - # accordingly, so it isn't necessary to maintain backward - # compatibility here when the attribute changes to - # replication_desired. + test "Set replication_desired=#{ask.inspect}" do + Rails.configuration.default_collection_replication = 2 authorize_with :active put :update, { - id: collections(:collection_owned_by_active).uuid, + id: collections(:replication_undesired_unconfirmed).uuid, collection: { - redundancy: ask, + replication_desired: ask, }, } assert_response :success - assert_equal (ask or 2), json_response['replication_desired'] + assert_equal ask, json_response['replication_desired'] + end + end + + test "get collection with properties" do + authorize_with :active + get :show, {id: collections(:collection_with_one_property).uuid} + assert_response :success + assert_not_nil json_response['uuid'] + assert_equal 'value1', json_response['properties']['property1'] + end + + test "create collection with properties" do + authorize_with :active + manifest_text = ". d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt\n" + post :create, { + collection: { + manifest_text: manifest_text, + portable_data_hash: "d30fe8ae534397864cb96c544f4cf102+47", + properties: {'property_1' => 'value_1'} + } + } + assert_response :success + assert_not_nil json_response['uuid'] + assert_equal 'value_1', json_response['properties']['property_1'] + end + + [ + ". 0:0:foo.txt", + ". d41d8cd98f00b204e9800998ecf8427e foo.txt", + "d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt", + ". d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt", + ].each do |manifest_text| + test "create collection with invalid manifest #{manifest_text} and expect error" do + authorize_with :active + post :create, { + collection: { + manifest_text: manifest_text, + portable_data_hash: "d41d8cd98f00b204e9800998ecf8427e+0" + } + } + assert_response 422 + response_errors = json_response['errors'] + assert_not_nil response_errors, 'Expected error in response' + assert(response_errors.first.include?('Invalid manifest'), + "Expected 'Invalid manifest' error in #{response_errors.first}") + end + end + + [ + [nil, "d41d8cd98f00b204e9800998ecf8427e+0"], + ["", "d41d8cd98f00b204e9800998ecf8427e+0"], + [". d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt\n", "d30fe8ae534397864cb96c544f4cf102+47"], + ].each do |manifest_text, pdh| + test "create collection with valid manifest #{manifest_text.inspect} and expect success" do + authorize_with :active + post :create, { + collection: { + manifest_text: manifest_text, + portable_data_hash: pdh + } + } + assert_response 200 + end + end + + [ + ". 0:0:foo.txt", + ". d41d8cd98f00b204e9800998ecf8427e foo.txt", + "d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt", + ". d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt", + ].each do |manifest_text| + test "update collection with invalid manifest #{manifest_text} and expect error" do + authorize_with :active + post :update, { + id: 'zzzzz-4zz18-bv31uwvy3neko21', + collection: { + manifest_text: manifest_text, + } + } + assert_response 422 + response_errors = json_response['errors'] + assert_not_nil response_errors, 'Expected error in response' + assert(response_errors.first.include?('Invalid manifest'), + "Expected 'Invalid manifest' error in #{response_errors.first}") + end + end + + [ + nil, + "", + ". d41d8cd98f00b204e9800998ecf8427e 0:0:foo.txt\n", + ].each do |manifest_text| + test "update collection with valid manifest #{manifest_text.inspect} and expect success" do + authorize_with :active + post :update, { + id: 'zzzzz-4zz18-bv31uwvy3neko21', + collection: { + manifest_text: manifest_text, + } + } + assert_response 200 end end end