7204: Fixed bugs in tests for `arg get`.
[arvados.git] / sdk / cli / test / test_arv-get.rb
1 require 'minitest/autorun'
2 require 'json'
3 require 'yaml'
4
5 # Black box tests for 'arv get' command.
6 class TestArvGet < Minitest::Test
7   # UUID for an Arvados object that does not exist
8   NON_EXISTANT_OBJECT_UUID = "qr1hi-tpzed-p9yk1lihjsgwew0"
9   # Name of field of Arvados object that can store any (textual) value
10   STORED_VALUE_FIELD_NAME = "name"
11   # Name of UUID field of Arvados object
12   UUID_FIELD_NAME = "uuid"
13   # Name of an invalid field of Arvados object
14   INVALID_FIELD_NAME = "invalid"
15
16   # Tests that a valid Arvados object can be retrieved in a supported format
17   # using: `arv get [uuid]`. Given all other `arv foo` commands return JSON
18   # when no format is specified, JSON should be expected in this case.
19   def test_get_valid_object_no_format()
20     stored_value = __method__
21     uuid = create_arv_object_with_value(stored_value)
22     out, err = capture_subprocess_io do
23       arv_get(uuid)
24     end
25     assert_empty(err)
26     refute_empty(out)
27     arv_object = parse_json_arv_object(out)
28     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
29   end
30
31   # Tests that a valid Arvados object can be retrieved in JSON format using:
32   # `arv get [uuid] --format json`.
33   def test_get_valid_object_json_format()
34     stored_value = __method__
35     uuid = create_arv_object_with_value(stored_value)
36     out, err = capture_subprocess_io do
37       arv_get(uuid, '--format', 'json')
38     end
39     assert_empty(err)
40     refute_empty(out)
41     arv_object = parse_json_arv_object(out)
42     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
43   end
44
45   # Tests that a valid Arvados object can be retrieved in YAML format using:
46   # `arv get [uuid] --format yaml`.
47   def test_get_valid_object_yaml_format()
48     stored_value = __method__
49     uuid = create_arv_object_with_value(stored_value)
50     out, err = capture_subprocess_io do
51       arv_get(uuid, '--format', 'yaml')
52     end
53     assert_empty(err)
54     refute_empty(out)
55     arv_object = parse_yaml_arv_object(out)
56     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
57   end
58
59   # Tests that a subset of all fields of a valid Arvados object can be retrieved
60   # using: `arv get [uuid] [fields...]`.
61   def test_get_valid_object_with_specific_valid_fields()
62     stored_value = __method__
63     uuid = create_arv_object_with_value(stored_value)
64     out, err = capture_subprocess_io do
65       arv_get(uuid, STORED_VALUE_FIELD_NAME, UUID_FIELD_NAME, "--format", "json")
66     end
67     assert_empty(err)
68     refute_empty(out)
69     arv_object = parse_json_arv_object(out)
70     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
71     assert(has_field_with_value(arv_object, UUID_FIELD_NAME, uuid))
72   end
73
74   # Tests that the valid field is retrieved when both a valid and invalid field
75   # are requested from a valid Arvados object, using:
76   # `arv get [uuid] [fields...]`.
77   def test_get_valid_object_with_both_specific_valid_and_invalid_fields()
78     stored_value = __method__
79     uuid = create_arv_object_with_value(stored_value)
80     out, err = capture_subprocess_io do
81       arv_get(uuid, STORED_VALUE_FIELD_NAME, INVALID_FIELD_NAME, "--format", "json")
82     end
83     assert_empty(err)
84     refute_empty(out)
85     arv_object = parse_json_arv_object(out)
86     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
87     refute(has_field_with_value(arv_object, INVALID_FIELD_NAME, stored_value))
88   end
89
90   # Tests that no fields are retreived when no valid fields are requested from
91   # a valid Arvados object, using: `arv get [uuid] [fields...]`.
92   def test_get_valid_object_with_no_specific_valid_fields()
93     stored_value = __method__
94     uuid = create_arv_object_with_value(stored_value)
95     out, err = capture_subprocess_io do
96       arv_get(uuid, INVALID_FIELD_NAME, "--format", "json")
97     end
98     assert_empty(err)
99     refute_empty(out)
100     arv_object = parse_json_arv_object(out)
101     assert_equal(0, arv_object.fixnum)
102   end
103
104   # Tests that an valid Arvados object is not retrieved when specifying an
105   # invalid format: `arv get [uuid] --format invalid`.
106   def test_get_valid_object_invalid_format()
107     stored_value = __method__
108     uuid = create_arv_object_with_value(stored_value)
109     out, err = capture_subprocess_io do
110       arv_get(uuid, '--format', 'invalid')
111     end
112     refute_empty(err)
113     assert_empty(out)
114   end
115
116   # Tests that an invalid (non-existant) Arvados object is not retrieved using:
117   # using: `arv get [non-existant-uuid]`.
118   def test_get_invalid_object()
119     out, err = capture_subprocess_io do
120       arv_get(NON_EXISTANT_OBJECT_UUID, "--format", "json")
121     end
122     refute_empty(err)
123     assert_empty(out)
124   end
125
126   # Tests that help text exists using: `arv get --help`.
127   def test_help_exists()
128     out, err = capture_subprocess_io do
129       arv_get("--help")
130     end
131     assert_empty(err)
132     refute_empty(out)
133   end
134
135   protected
136   # Runs 'arv get <varargs>' with given arguments.
137   def arv_get(*args)
138     system(['./bin/arv', 'get'], *args)
139   end
140
141   # Creates an Arvados object that stores a given value. Returns the uuid of the
142   # created object.
143   def create_arv_object_with_value(value)
144       out, err = capture_subprocess_io do
145         # Write (without redirect)
146         system(['./bin/arv', "tag add #{value} --object testing"])
147       end
148       if err.length > 0
149         raise "Could not create Arvados object with given value"
150       end
151       return out
152   end
153
154   # Parses the given JSON representation of an Arvados object, returning
155   # an equivalent Ruby representation (a hash map).
156   def parse_json_arv_object(arvObjectAsJson)
157     begin
158       parsed = JSON.parse(arvObjectAsJson)
159       assert(parsed.instance_of?(Hash))
160       return parsed
161     rescue JSON::ParserError => e
162       raise "Invalid JSON representation of Arvados object.\n" \
163             "Parse error: #{e}\n" \
164             "JSON: #{arvObjectAsJson}\n"
165     end
166   end
167
168   # Parses the given JSON representation of an Arvados object, returning
169   # an equivalent Ruby representation (a hash map).
170   def parse_yaml_arv_object(arvObjectAsYaml)
171     begin
172       parsed = YAML.load(arvObjectAsYaml)
173       assert(parsed.instance_of?(Hash))
174       return parsed
175     rescue
176       raise "Invalid YAML representation of Arvados object.\n" \
177             "YAML: #{arvObjectAsYaml}\n"
178     end
179   end
180
181   # Checks whether the given Arvados object has the given expected value for the
182   # specified field.
183   def has_field_with_value(arvObjectAsHash, fieldName, expectedValue)
184     if !arvObjectAsHash.has_key?(fieldName)
185       return false
186     end
187     return (arvObjectAsHash[fieldName] == expectedValue)
188   end
189 end