avoid file descriptor leak in replication
[iwhd.git] / t / basic
blob808d62a7aad8f680802fc91d9dcb78c946abe89d
1 #!/bin/sh
2 # Test basic functionality.
4 # TEST-FILE USAGE
5 # obj_test object put/get/delete
6 # list_test bucket listing
7 # attr_put attribute PUT, headless operation
8 # attr_post attribute POST
9 # rsvd_attr reserved attr
10 # role_test X-redhat-role
11 # trunc_test truncation
13 . "${srcdir=.}/init.sh"; path_prepend_ ..
15 mkdir FS mongod iwhd || framework_failure_ mkdir failed
17 m_port=$(expr $mongo_base_port + 0)
19 mongod --port $m_port --pidfilepath mongod/pid --dbpath mongod > mongod.log 2>&1 &
20 mongo_pid=$!
21 cleanup_() { kill -9 $mongo_pid; }
23 # Wait for up to 5 seconds for mongod to begin listening.
24 wait_for .1 50 'mongo localhost:$m_port < /dev/null' \
25 || framework_failure_ mongod failed to start
27 port=9091
28 bucket=http://localhost:$port/b1
30 cat <<EOF > root.xml || framework_failure_
31 <api service="image_warehouse" version="$VERSION">
32 <link rel="bucket_factory" href="http://localhost:$port/_new"/>
33 <link rel="provider_list" href="http://localhost:$port/_providers"/>
34 <link rel="bucket" href="$bucket"/>
35 </api>
36 EOF
38 cat <<EOF > root.json || framework_failure_
40 "service": "image_warehouse",
41 "version": "$VERSION",
44 "rel": "bucket_factory",
45 "link": "http://localhost:$port/_new"
48 "rel": "provider_list",
49 "link": "http://localhost:$port/_providers"
52 "rel": "bucket",
53 "link": "$bucket"
57 EOF
59 printf '[{"path": "FS", "type": "fs", "name": "primary"}]\n' \
60 > iwhd.cfg || fail=1
62 iwhd -v -p $port -c iwhd.cfg -d localhost:$m_port &
63 iwhd_pid=$!
64 cleanup_() { kill -9 $mongo_pid; kill $iwhd_pid; }
66 # Wait for up to 5 seconds for iwhd to begin listening on $port.
67 wait_for .1 50 "curl -s http://localhost:$port" \
68 || { echo iwhd failed to listen; Exit 1; }
70 # Create an empty bucket.
71 curl -X PUT $bucket || fail=1
72 test -d FS/b1 || fail=1
74 # Try to create a duplicate bucket.
75 curl -f -X PUT $bucket 2> dup_bucket.err
76 grep ' 500$' dup_bucket.err || fail=1
78 # PUT to root; should fail
79 curl -f -X PUT http://localhost:$port 2> root_put.err
80 grep ' 404$' root_put.err || fail=1
82 # Create a file in that bucket.
83 echo foo | curl -T - $bucket/obj_test || fail=1
84 # Test presence in the FS.
85 test -f FS/b1/obj_test || fail=1
86 test "$(cat FS/b1/obj_test)" = foo || fail=1
87 # Test through the API as well.
88 curl $bucket/obj_test > f1copy
89 test "$(cat f1copy)" = foo || fail=1
92 # Get root; default, then Accept: XML & JSON:
93 curl http://localhost:$port > root || fail=1
94 compare root root.xml || fail=1
96 curl -H 'Accept: */xml' http://localhost:$port > root || fail=1
97 compare root root.xml || fail=1
99 curl -H 'Accept: */json' http://localhost:$port > root || fail=1
100 compare root root.json || fail=1
102 # Delete an object.
103 curl -X DELETE $bucket/obj_test || fail=1
104 # Ensure that it's gone from the file system.
105 test -f FS/b1/obj_test && fail=1
106 # Ensure that it's gone in the API as well.
107 curl -f $bucket/obj_test > /dev/null 2> del_object.err
108 grep ' 404$' del_object.err || fail=1
110 # Try to delete a nonexistent object.
111 curl -f -X DELETE $bucket/no-such-obj 2> del_nosuch.err
112 grep ' 404$' del_nosuch.err || fail=1
114 # Make sure the X-redhat-role header causes failure on a master iwhd.
115 echo hello | curl -f -T - -H "X-redhat-role: master" $bucket/role_test \
116 2> role.err
117 grep ' 403$' role.err || fail=1
119 # ################## Providers
121 p_name=primary
123 # Verify that default provider's information is as expected.
124 curl http://localhost:$port/_providers > p || fail=1
125 emit_trivial_provider_list xml "$p_name" fs '' 0 '' '' is-last > p.exp || fail=1
126 compare p.exp p || fail=1
128 for i in xml json; do
130 curl_H() { curl -H "Accept: */$i" "$@"; }
132 # List an empty bucket.
133 curl_H $bucket > b || fail=1
134 emit_bucket_list $i > b.exp || fail=1
135 compare b.exp b || fail=1
137 # Add an object, list non-empty bucket.
138 echo bar | curl -T - $bucket/list_test || fail=1
140 # Ensure that new name appears in the listing.
141 curl_H $bucket > b || fail=1
142 emit_bucket_list $i b1:list_test > b.exp || fail=1
143 compare b.exp b || fail=1
145 # Remove b1/list_test, to restore state for next iteration of this loop.
146 curl -X DELETE $bucket/list_test || fail=1
148 done
150 # Crash reported by Steve Loranz
151 curl -f -X PUT http://localhost:$port/b99
152 echo hello | curl -T - http://localhost:$port/b99/my_file
153 printf mock | curl -T - http://localhost:$port/b99/my_file/target
154 curl -H 'Accept: */json' -d '$target=="mock"' \
155 http://localhost:$port/b99/_query > q.xml
156 tr -s '\t \n' ' ' < q.xml > k && mv k q.xml
157 printf '[ { "bucket": "b99", "key": "my_file" } ] ' > exp.xml
158 compare q.xml exp.xml || fail=1
160 # Before 2011-02-07, this would cause iwhd to hang.
161 printf hang | curl -T - http://localhost:$port/no-such/fff
163 # Add a single attribute to an object using the PUT method.
164 bucket=$bucket
165 printf nothing | curl -T - $bucket/attr_put || fail=1
166 printf blue | curl -T - $bucket/attr_put/color || fail=1
167 test "$(curl $bucket/attr_put/color)" = blue || fail=1
169 # Add multiple attributes to an object using the POST method.
170 # NB use a file which doesn't yet exist (yes, this should work too)
171 curl -d _key=attr_post -d shape=round -d size=big $bucket || fail=1
172 test "$(curl $bucket/attr_post/shape)" = round || fail=1
173 test "$(curl $bucket/attr_post/size)" = big || fail=1
175 # Ensure that an attempt to add reserved object name fails.
176 # FIXME: keep this list in sync with the one in rest.c:
177 # grep '^static.*reserved_name' rest.c
178 for obj_name in _default _new _policy _query; do
179 echo reserved-obj-name | curl -f -T - $bucket/$obj_name 2> bad_oname.err
180 # _query evokes 404. all others evoke 403
181 case $obj_name in
182 _query) exp=404;;
183 *) exp=403;;
184 esac
185 grep " $exp\$" bad_oname.err || fail=1
186 done
188 # Ensure that an attempt to add each reserved attribute fails.
189 # FIXME: keep this list in sync with the one in rest.c:
190 # grep '^static.*reserved_attr' rest.c
191 for attr in _bucket _key _date _etag _loc _size; do
192 printf whatever | curl -f -T - $bucket/rsvd_attr/$attr 2> bad_attr.err
193 grep ' 400$' bad_attr.err || fail=1
194 done
196 # Ensure that an attempt to create a bucket with a reserved name fails.
197 # FIXME: keep this list in sync with the one in rest.c:
198 # grep '^static.*reserved_bucket_name' rest.c
199 for b in _new _providers; do
200 invalid_bucket=http://localhost:$port/$b
201 curl -f -X PUT $invalid_bucket 2> invalid_bucket.err
202 # FIXME: change the code so that these are the same
203 case $b in
204 _new) exp=400;; # MHD_HTTP_BAD_REQUEST
205 *) exp=404;;
206 esac
207 cat invalid_bucket.err
208 grep " $exp\$" invalid_bucket.err || fail=1
209 done
211 # Make sure PUTting a file truncates.
212 echo hello | curl -f -T - $bucket/trunc_test || fail=1
213 echo bye | curl -f -T - $bucket/trunc_test || fail=1
214 cat FS/b1/trunc_test
215 test "$(cat FS/b1/trunc_test)" = bye || fail=1
217 # TBD: add attribute-delete tests when that functionality is implemented
219 # TBD: add white-box tests for attributes in mongo
221 # Add a provider:
222 p1_url=http://localhost:$port/_providers/PROVIDER-1
223 curl -d type=s3 -dhost=localhost -dport=80 -dkey=u -dsecret=p \
224 $p1_url || fail=1
226 # Ensure it was added
227 curl http://localhost:$port/_providers > p || fail=1
228 grep PROVIDER-1 p || fail=1
230 # Add another provider:
231 p2_url=http://localhost:$port/_providers/PROVIDER-2
232 curl -dtype=http -dhost=localhost -dport=9091 $p2_url || fail=1
233 # Ensure it was added.
234 curl http://localhost:$port/_providers > p || fail=1
235 grep PROVIDER-2 p || fail=1
237 # Add provider using a "name" parameter (not permitted):
238 p3_url=http://localhost:$port/_providers/PROVIDER-3
239 curl -dtype=http -dname=X -dhost=localhost -dport=9091 $p3_url || fail=1
240 # Ensure it was not added.
241 curl http://localhost:$port/_providers > p || fail=1
242 grep PROVIDER-3 p && { warn_ add-provider-w/name-param not rejected; fail=1; }
244 # Delete a provider.
245 curl -f -X DELETE $p2_url 2> p || fail=1
246 # Ensure it was deleted.
247 curl http://localhost:$port/_providers > p || fail=1
248 grep PROVIDER-2 p && { warn_ $ME_: provider deletion failed; fail=1; }
250 # Delete a non-existent provider.
251 curl -f -X DELETE http://localhost:$port/_providers/no-such 2> p
252 # ensure it fails; expect exit-22 and http: 404
253 test $? = 22 || fail=1
254 grep ' 404$' p || fail=1
256 # Get the name of the current primary provider.
257 curl http://localhost:$port/_providers/_primary > p || fail=1
258 test "$(cat p)" = primary || fail=1
260 # Trying to GET with anything other than "_primary" returns the empty string.
261 curl http://localhost:$port/_providers/anything > p 2>/dev/null || fail=1
262 test -s p && fail=1
264 # Try to add a provider with the reserved name. It must fail.
265 p_reserved_url=http://localhost:$port/_providers/_primary
266 curl -dtype=http -dhost=localhost -dport=9091 $p_reserved_url || fail=1
267 # Ensure it was not added.
268 curl http://localhost:$port/_primary > p || fail=1
269 grep _primary p && { warn_ add-provider/reserved-name not rejected; fail=1; }
271 # Move the "primary" attribute to a different provider.
272 curl -X PUT $p1_url/_primary > p || fail=1
273 test -s p && fail=1
274 new_primary=$(curl http://localhost:$port/_providers/_primary) || fail=1
275 test "$new_primary" = PROVIDER-1 || fail=1
277 # Restore the primary attribute to the original.
278 # FIXME: if I don't restore, the following headless test makes iwhd segfault.
279 # Investigate that.
280 p1_url=http://localhost:$port/_providers/primary
281 curl -X PUT $p1_url/_primary > p || fail=1
285 # Test "headless" operation (no access to metadata DB).
286 kill -9 $mongo_pid
287 cleanup_() { kill $iwhd_pid; }
288 curl $bucket/attr_put > f3copy
289 test "$(cat f3copy)" = "nothing" || fail=1
291 Exit $fail