6859: add test that creates and salvages a collection with invalid manifest text.
[arvados.git] / services / api / test / unit / salvage_collection_test.rb
1 require 'test_helper'
2 require 'salvage_collection'
3
4 # Valid manifest_text
5 TEST_MANIFEST = ". 341dabea2bd78ad0d6fc3f5b926b450e+85626+Ad391622a17f61e4a254eda85d1ca751c4f368da9@55e076ce 0:85626:brca2-hg19.fa\n. d7321a918923627c972d8f8080c07d29+82570+A22e0a1d9b9bc85c848379d98bedc64238b0b1532@55e076ce 0:82570:brca1-hg19.fa\n"
6
7 # This invalid manifest_text has the following flaws:
8 #   Missing stream name with locator in it's place
9 #   Two invalid locators:
10 #     341dabea2bd78ad0d6fc3f5b926b450e+abc
11 #     341dabea2bd78ad0d6fc3f5b926b450e
12 # Expectation: These locators are preserved in salvaged_data
13 BAD_MANIFEST = "341dabea2bd78ad0d6fc3f5b926b450e+abc 341dabea2bd78ad0d6fc3f5b926abcdf 0:85626:brca2-hg19.fa\n. abcdabea2bd78ad0d6fc3f5b926b450e+1000 0:1000:brca-hg19.fa\n . d7321a918923627c972d8f8080c07d29+2000+A22e0a1d9b9bc85c848379d98bedc64238b0b1532@55e076ce 0:2000:brca1-hg19.fa\n"
14
15 # Mock arv_put
16 module SalvageCollection
17   def self.salvage_collection_arv_put(cmd)
18     file_contents = File.new(cmd.split[-1], "r").gets
19
20     # simulate arv-put error when it is 'user_agreement'
21     if file_contents.include? 'GNU_General_Public_License'
22       raise("Error during arv-put")
23     else
24       ". " +
25       Digest::MD5.hexdigest(TEST_MANIFEST) + "+" + TEST_MANIFEST.length.to_s +
26       " 0:" + TEST_MANIFEST.length.to_s + ":invalid_manifest_text.txt\n"
27     end
28   end
29 end
30
31 class SalvageCollectionTest < ActiveSupport::TestCase
32   include SalvageCollection
33
34   setup do
35     set_user_from_auth :admin
36     # arv-put needs ARV env variables
37     ENV['ARVADOS_API_HOST'] = 'unused_by_test'
38     ENV['ARVADOS_API_TOKEN'] = 'unused_by_test'
39   end
40
41   teardown do
42     ENV['ARVADOS_API_HOST'] = ''
43     ENV['ARVADOS_API_TOKEN'] = ''
44   end
45
46   test "salvage test collection with valid manifest text" do
47     # create a collection to test salvaging
48     src_collection = Collection.new name: "test collection", manifest_text: TEST_MANIFEST
49     src_collection.save!
50
51     # salvage this collection
52     SalvageCollection.salvage_collection src_collection.uuid, 'test salvage collection - see #6277, #6859'
53
54     # verify the updated src_collection data
55     updated_src_collection = Collection.find_by_uuid src_collection.uuid
56     updated_name = updated_src_collection.name
57     assert_equal true, updated_name.include?(src_collection.name)
58
59     match = updated_name.match /^test collection.*salvaged data at (.*)\)$/
60     assert_not_nil match
61     assert_not_nil match[1]
62     assert_empty updated_src_collection.manifest_text
63
64     # match[1] is the uuid of the new collection created from src_collection's salvaged data
65     # use this to get the new collection and verify
66     new_collection = Collection.find_by_uuid match[1]
67     match = new_collection.name.match /^salvaged from (.*),.*/
68     assert_not_nil match
69     assert_equal src_collection.uuid, match[1]
70
71     # verify the new collection's manifest format
72     match = new_collection.manifest_text.match /^. (.*) (.*):invalid_manifest_text.txt\n. (.*) (.*):salvaged_data/
73     assert_not_nil match
74   end
75
76   test "salvage collection with no uuid required argument" do
77     e = assert_raises RuntimeError do
78       SalvageCollection.salvage_collection nil
79     end
80   end
81
82   test "salvage collection with bogus uuid" do
83     e = assert_raises RuntimeError do
84       SalvageCollection.salvage_collection 'bogus-uuid'
85     end
86     assert_equal "No collection found for bogus-uuid.", e.message
87   end
88
89   test "salvage collection with no env ARVADOS_API_HOST" do
90     e = assert_raises RuntimeError do
91       ENV['ARVADOS_API_HOST'] = ''
92       ENV['ARVADOS_API_TOKEN'] = ''
93       SalvageCollection.salvage_collection collections('user_agreement').uuid
94     end
95     assert_equal "ARVADOS environment variables missing. Please set your admin user credentials as ARVADOS environment variables.", e.message
96   end
97
98   test "salvage collection with error during arv-put" do
99     # try to salvage collection while mimicking error during arv-put
100     e = assert_raises RuntimeError do
101       SalvageCollection.salvage_collection collections('user_agreement').uuid
102     end
103     assert_equal "Error during arv-put", e.message
104   end
105
106   # This test uses BAD_MANIFEST, which has the following flaws:
107   #   Missing stream name with locator in it's place
108   #   Two invalid locators:
109   #     341dabea2bd78ad0d6fc3f5b926b450e+abc
110   #     341dabea2bd78ad0d6fc3f5b926b450e
111   # Expectation: These locators are preserved in salvaged_data
112   test "invalid locators preserved during salvaging" do
113     locator_data = SalvageCollection.salvage_collection_locator_data BAD_MANIFEST
114     assert_equal true, locator_data[0].size.eql?(4)
115     assert_equal false, locator_data[0].include?("341dabea2bd78ad0d6fc3f5b926b450e+abc")
116     assert_equal true, locator_data[0].include?("341dabea2bd78ad0d6fc3f5b926b450e")
117     assert_equal true, locator_data[0].include?("341dabea2bd78ad0d6fc3f5b926abcdf")
118     assert_equal true, locator_data[0].include?("abcdabea2bd78ad0d6fc3f5b926b450e+1000")
119     assert_equal true, locator_data[0].include?("d7321a918923627c972d8f8080c07d29+2000")
120     assert_equal true, locator_data[1].eql?(1000 + 2000)   # size
121   end
122
123   test "salvage a collection with invalid manifest text" do
124     # create a collection to test salvaging
125     src_collection = Collection.new name: "test collection", manifest_text: BAD_MANIFEST, owner_uuid: 'zzzzz-tpzed-000000000000000'
126     src_collection.save!(validate: false)
127
128     # salvage this collection
129     SalvageCollection.salvage_collection src_collection.uuid, 'test salvage collection - see #6277, #6859'
130
131     # verify the updated src_collection data
132     updated_src_collection = Collection.find_by_uuid src_collection.uuid
133     updated_name = updated_src_collection.name
134     assert_equal true, updated_name.include?(src_collection.name)
135
136     match = updated_name.match /^test collection.*salvaged data at (.*)\)$/
137     assert_not_nil match
138     assert_not_nil match[1]
139     assert_empty updated_src_collection.manifest_text
140
141     # match[1] is the uuid of the new collection created from src_collection's salvaged data
142     # use this to get the new collection and verify
143     new_collection = Collection.find_by_uuid match[1]
144     match = new_collection.name.match /^salvaged from (.*),.*/
145     assert_not_nil match
146     assert_equal src_collection.uuid, match[1]
147
148     # verify the new collection's manifest includes the bad locators
149     match = new_collection.manifest_text.match /^. (.*) (.*):invalid_manifest_text.txt\n. (.*) (.*):salvaged_data/
150     assert_not_nil match
151     assert_includes(new_collection.manifest_text, ". 341dabea2bd78ad0d6fc3f5b926b450e 341dabea2bd78ad0d6fc3f5b926abcdf abcdabea2bd78ad0d6fc3f5b926b450e+1000 d7321a918923627c972d8f8080c07d29+2000 0:3000:salvaged_data")
152   end
153 end