   (:require [clojure.test :refer :all])
   (:import (com.puppetlabs.puppetserver.pool JRubyPool)
            (java.util.concurrent TimeUnit ExecutionException)))
+
+(defn timed-deref
+  [ref]
+  (deref ref 10000 :timed-out))
 
 (defn create-empty-pool
   [size]

          (is (not (realized? lock-thread)))
          (.unregister pool (second instances)))

        @lock-acquired?
        (is (not (realized? lock-thread)))
        (is (.isLocked pool))
        (deliver unlock? true)
        @lock-thread
        (is (not (.isLocked pool)))))

    (let [future-started? (promise)
          last-instance (.borrowItem pool)
          lock-thread (future (deliver future-started? true)
                              (.lock pool))]
      @future-started?
      (testing "pool.lock() blocks until last borrowed instance is unregistered"
        (is (not (realized? lock-thread)))

          borrow-thread (future (deliver borrow-thread-started? true)
                                (let [instance (.borrowItem pool)]
                                  (deliver borrow-thread-borrowed? true)
                                  (.releaseItem pool instance))
                                true)]
      @borrow-thread-started?
      (is (not (realized? borrow-thread-borrowed?)))
      (.releaseItem pool item)
      (is (true? (timed-deref borrow-thread))
          "timed out waiting for borrow thread to finish"))))

(deftest pool-timed-borrows-test
  (testing "pool borrows with timeout"
    (let [pool (create-populated-pool 1)
          item (.borrowItem pool)]
      (testing "borrow times out and returns nil when pool is empty"
        (is (nil? (timed-deref
                   (future (.borrowItemWithTimeout pool
                                                   1
                                                   TimeUnit/MICROSECONDS))))))
      (.releaseItem pool item)
      (testing "borrow succeeds when pool is non-empty"
        (is (identical? item (timed-deref
                              (future (.borrowItemWithTimeout
                                       pool
                                       1
                                       TimeUnit/MICROSECONDS)))))))))

(deftest pool-can-do-blocking-borrow-after-borrow-timed-out
  (testing "can do blocking borrow from pool after previous borrow timed out"
