    :proxy {:host riak-cs-host
            :port (get-riak-cs-port)}})
 
+(defn random-user
+  []
+  (user-creation/create-random-user riak-cs-host-with-protocol (get-riak-cs-port)))
+
+(defmacro with-random-user
+  "Execute `body` in implicit do with a random-user bound to `var-name`"
+  [var-name & body]
+  `(let [~var-name (random-user)]
+     (do ~@body)))
+
 (defn random-cred
   []
-  (let [new-cred (user-creation/create-random-user
-                   riak-cs-host-with-protocol
-                   (get-riak-cs-port))]
-    (user-to-cred new-cred)))
+  (user-to-cred (random-user)))
 
 (defmacro with-random-cred
-  "Execute `form` with a random-cred
-  bound to `var-name`"
-  [var-name form]
+  "Execute `body` in implicit do with a random-cred bound to `var-name`"
+  [var-name & body]
   `(let [~var-name (random-cred)]
-     ~form))
+     (do ~@body)))
 
 (defn random-string []
   (str (java.util.UUID/randomUUID)))
 
 (defn write-file [filename content]
-  (with-open [w (clojure.java.io/writer  filename :append false)]
+  (with-open [w (clojure.java.io/writer filename :append false)]
     (.write w content)))
 
 (defn etag-suffix [etag]

  (fact "Creating an object with an ACL returns the same ACL when you read
        the ACL"
        (with-random-cred c
          (do
            ;; create a bucket
            (s3/create-bucket c bucket-name)
            (s3/put-object c bucket-name object-name value-string {}
                           (s3/grant :all-users :read))
            (contains?
             (:grants (s3/get-object-acl c bucket-name object-name))
             public-read-grant)))
        => truthy))

(let [bucket-name (random-string)
      object-name (random-string)
      value-string "this is the real value"]
  (fact "Creating an object with an (non-canned) ACL returns the same ACL
        when you read the ACL"
        (with-random-cred c
          (do
            (s3/create-bucket c bucket-name)
            (let [user-two (user-creation/create-random-user
                            riak-cs-host-with-protocol
                            (get-riak-cs-port))
                  user-two-id (:id user-two)
                  user-two-name (:display_name user-two)
                  acl-grant {:grantee {:id user-two-id, :display-name user-two-name},
                             :permission :read}]
              (s3/put-object c bucket-name object-name value-string {}
                             (s3/grant {:id user-two-id} :read))
              (contains?
                (:grants (s3/get-object-acl c bucket-name object-name))
                acl-grant))))
        => truthy))

(let [bucket-name (random-string)
      object-name (random-string)
      public-read-grant {:grantee :all-users, :permission :read}]
  (fact "Creating a bucket with an ACL returns the same ACL when you read
        the ACL"
        (with-random-cred c
          (do
            (s3/create-bucket c bucket-name {}
                              (s3/grant :all-users :read))
            (contains?
             (:grants (s3/get-bucket-acl c bucket-name))
             public-read-grant)))
        => truthy))

(let [bucket-name (random-string)
      object-name (random-string)]
  (fact "Creating a bucket with an (non-canned) ACL returns the same ACL
        when you read the ACL"
        (with-random-cred c
          (do
            (let [user-two (user-creation/create-random-user
                            riak-cs-host-with-protocol
                            (get-riak-cs-port))
                  user-two-id (:id user-two)
                  user-two-name (:display_name user-two)
                  acl-grant {:grantee {:id user-two-id, :display-name user-two-name},
                             :permission :write}]
              (s3/create-bucket c bucket-name {}
                                (s3/grant {:id user-two-id} :write))
              (contains?
               (:grants (s3/get-bucket-acl c bucket-name))
               acl-grant))))
        => truthy))

      value "this is the value!"
      as-bytes (.getBytes value "UTF-8")
      md5-sum (md5-string as-bytes)]
  (fact "check that the etag of the response is the same as the md5
         of the original object"
        (with-random-cred c
          (s3/create-bucket c bucket-name)
          (s3/put-object c bucket-name object-name value)
          ((comp :etag :metadata)
           (s3/get-object
            c bucket-name object-name)))
        => md5-sum))

(let [bucket-name (random-string)
      object-name (random-string)
      value "aaaaaaaaaabbbbbbbbbb"
      file-name "./clj-mp-test.txt"]
  (fact "multipart upload works"
        (with-random-cred c
          (s3/create-bucket c bucket-name)
          (write-file file-name value)
          (upload-file c bucket-name object-name file-name 10)
          (let [fetched-object (s3/get-object
                                c bucket-name object-name)]
            ((comp slurp :content) fetched-object)
            => value
            ((comp etag-suffix :etag :metadata) fetched-object)
            => "-2"))))

(let [bucket-name (random-string)
      object-name (random-string)
