8005: Add tar Ruby build dependency on CentOS 6.
[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_EXISTENT_OBJECT_UUID = "zzzzz-zzzzz-zzzzzzzzzzzzzzz"
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_specified
20     stored_value = __method__.to_s
21     uuid = create_arv_object_with_value(stored_value)
22     out, err = capture_subprocess_io do
23       assert(arv_get_default(uuid))
24     end
25     assert_empty(err, "Error text not expected: '#{err}'")
26     arv_object = parse_json_arv_object(out)
27     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
28   end
29
30   # Tests that a valid Arvados object can be retrieved in JSON format using:
31   # `arv get [uuid] --format json`.
32   def test_get_valid_object_json_format_specified
33     stored_value = __method__.to_s
34     uuid = create_arv_object_with_value(stored_value)
35     out, err = capture_subprocess_io do
36       assert(arv_get_json(uuid))
37     end
38     assert_empty(err, "Error text not expected: '#{err}'")
39     arv_object = parse_json_arv_object(out)
40     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
41   end
42
43   # Tests that a valid Arvados object can be retrieved in YAML format using:
44   # `arv get [uuid] --format yaml`.
45   def test_get_valid_object_yaml_format_specified
46     stored_value = __method__.to_s
47     uuid = create_arv_object_with_value(stored_value)
48     out, err = capture_subprocess_io do
49       assert(arv_get_yaml(uuid))
50     end
51     assert_empty(err, "Error text not expected: '#{err}'")
52     arv_object = parse_yaml_arv_object(out)
53     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
54   end
55
56   # Tests that a subset of all fields of a valid Arvados object can be retrieved
57   # using: `arv get [uuid] [fields...]`.
58   def test_get_valid_object_with_valid_fields
59     stored_value = __method__.to_s
60     uuid = create_arv_object_with_value(stored_value)
61     out, err = capture_subprocess_io do
62       assert(arv_get_json(uuid, STORED_VALUE_FIELD_NAME, UUID_FIELD_NAME))
63     end
64     assert_empty(err, "Error text not expected: '#{err}'")
65     arv_object = parse_json_arv_object(out)
66     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
67     assert(has_field_with_value(arv_object, UUID_FIELD_NAME, uuid))
68   end
69
70   # Tests that the valid field is retrieved when both a valid and invalid field
71   # are requested from a valid Arvados object, using:
72   # `arv get [uuid] [fields...]`.
73   def test_get_valid_object_with_both_valid_and_invalid_fields
74     stored_value = __method__.to_s
75     uuid = create_arv_object_with_value(stored_value)
76     out, err = capture_subprocess_io do
77       assert(arv_get_json(uuid, STORED_VALUE_FIELD_NAME, INVALID_FIELD_NAME))
78     end
79     assert_empty(err, "Error text not expected: '#{err}'")
80     arv_object = parse_json_arv_object(out)
81     assert(has_field_with_value(arv_object, STORED_VALUE_FIELD_NAME, stored_value))
82     refute(has_field_with_value(arv_object, INVALID_FIELD_NAME, stored_value))
83   end
84
85   # Tests that no fields are retreived when no valid fields are requested from
86   # a valid Arvados object, using: `arv get [uuid] [fields...]`.
87   def test_get_valid_object_with_no_valid_fields
88     stored_value = __method__.to_s
89     uuid = create_arv_object_with_value(stored_value)
90     out, err = capture_subprocess_io do
91       assert(arv_get_json(uuid, INVALID_FIELD_NAME))
92     end
93     assert_empty(err, "Error text not expected: '#{err}'")
94     arv_object = parse_json_arv_object(out)
95     assert_equal(0, arv_object.length)
96   end
97
98   # Tests that an invalid (non-existent) Arvados object is not retrieved using:
99   # using: `arv get [non-existent-uuid]`.
100   def test_get_invalid_object
101     out, err = capture_subprocess_io do
102       refute(arv_get_json(NON_EXISTENT_OBJECT_UUID))
103     end
104     refute_empty(err, "Expected error feedback on request for invalid object")
105     assert_empty(out)
106   end
107
108   # Tests that help text exists using: `arv get --help`.
109   def test_help_exists
110     out, err = capture_subprocess_io do
111 #      assert(arv_get_default("--help"), "Expected exit code 0: #{$?}")
112        #XXX: Exit code given is 255. It probably should be 0, which seems to be
113        #     standard elsewhere. However, 255 is in line with other `arv`
114        #     commands (e.g. see `arv edit`) so ignoring the problem here.
115        arv_get_default("--help")
116     end
117     assert_empty(err, "Error text not expected: '#{err}'")
118     refute_empty(out, "Help text should be given")
119   end
120
121   protected
122   # Runs 'arv get <varargs>' with given arguments. Returns whether the exit
123   # status was 0 (i.e. success). Use $? to attain more details on failure.
124   def arv_get_default(*args)
125     return system("arv", "get", *args)
126   end
127
128   # Runs 'arv --format json get <varargs>' with given arguments. Returns whether
129   # the exit status was 0 (i.e. success). Use $? to attain more details on
130   # failure.
131   def arv_get_json(*args)
132     return system("arv", "--format", "json", "get", *args)
133   end
134
135   # Runs 'arv --format yaml get <varargs>' with given arguments. Returns whether
136   # the exit status was 0 (i.e. success). Use $? to attain more details on
137   # failure.
138   def arv_get_yaml(*args)
139     return system("arv", "--format", "yaml", "get", *args)
140   end
141
142   # Creates an Arvados object that stores a given value. Returns the uuid of the
143   # created object.
144   def create_arv_object_with_value(value)
145     out, err = capture_subprocess_io do
146       system("arv", "tag", "add", value, "--object", "testing")
147       assert $?.success?, "Command failure running `arv tag`: #{$?}"
148     end
149     assert_equal '', err
150     assert_operator 0, :<, out.strip.length
151     out.strip
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