   (let [b (md5-byte-array input-byte-array)]
     (String. (Hex/encodeHex b))))
 
-(defn random-client
+(defn random-cred
   []
   (let [new-creds (user-creation/create-random-user
-                    riak-cs-host-with-protocol
-                    (get-riak-cs-port))]
-    (s3/client (:key_id new-creds)
-               (:key_secret new-creds)
-               {:proxy-host riak-cs-host
-                :proxy-port (get-riak-cs-port)
-                :protocol :http})))
-
-(defmacro with-random-client
-  "Execute `form` with a random-client
+                   riak-cs-host-with-protocol
+                   (get-riak-cs-port))]
+    {:endpoint "http://s3.amazonaws.com"
+     :access-key (:key_id new-creds)
+     :secret-key (:key_secret new-creds)
+     :proxy {:host riak-cs-host
+             :port (get-riak-cs-port)}}))
+
+(defmacro with-random-cred
+  "Execute `form` with a random-cred
   bound to `var-name`"
   [var-name form]
-  `(let [~var-name (random-client)]
+  `(let [~var-name (random-cred)]
      ~form))
 
 (defn random-string []

(defn etag-suffix [etag]
  (subs etag (- (count etag) 2)))

(defn create-manager [c]
  (TransferManager. c))

(defn configure-manager [tm]
  (let [tm-config (.getConfiguration tm)]
    (.setMultipartUploadThreshold tm-config 19)
    (.setMinimumUploadPartSize tm-config 10)
    (.setConfiguration tm tm-config)))

(defn create-and-configure-manager [c]
  (let [tm (create-manager c)]
    (configure-manager tm)
    tm))

(defn upload-file [tm bucket-name object-name file-name]
  (let [f (clojure.java.io/file file-name)
        u (.upload tm bucket-name object-name f)]
    (.waitForCompletion u)
    (.delete f)))

(fact "bogus creds raises an exception"
      (let [bogus-client
            (s3/client "foo"
                       "bar"
                       {:endpoint (str "http://localhost:"
                                       (get-riak-cs-port-str))})]
        (s3/list-buckets bogus-client))
      => (throws AmazonS3Exception))

(fact "new users have no buckets"
        (with-random-client c
          (s3/list-buckets c))
        => [])

(let [bucket-name (random-string)]
  (fact "creating a bucket should list
        one bucket in list buckets"
        (with-random-client c
          (do (s3/create-bucket c bucket-name)
            ((comp :name first) (s3/list-buckets c))))
        => bucket-name))

(let [bucket-name (random-string)
      object-name (random-string)]
  (fact "simple put works"
        (with-random-client c
          (do (s3/create-bucket c bucket-name)
            (s3/put-object c bucket-name object-name
                           "contents")))
        => truthy))

(let [bucket-name (random-string)

(def bad-canonical-id
  "0f80b2d002a3d018faaa4a956ce8aa243332a30e878f5dc94f82749984ebb30b")

(let [bucket-name (random-string)
      object-name (random-string)
      value-string "this is the real value"]
  (fact "Nonexistent canonical-id grant header returns HTTP 400 on
        a put object request (not just an ACL subresource request)"
        (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 {:id bad-canonical-id} :full-control))))
        => (throws AmazonS3Exception)))

(let [bucket-name (random-string)
      object-name (random-string)
      value-string "this is the real value"
      public-read-grant {:grantee :all-users, :permission :read}]
  (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"
      public-read-grant {:grantee :all-users, :permission :read}]
  (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)
