[rhmessaging-commits] rhmessaging commits: r1599 - in store/trunk/cpp: tests/jrnl/jtt and 1 other directory.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Wed Jan 23 15:31:53 EST 2008


Author: kpvdr
Date: 2008-01-23 15:31:53 -0500 (Wed, 23 Jan 2008)
New Revision: 1599

Added:
   store/trunk/cpp/tests/jrnl/jtt/options.cpp
   store/trunk/cpp/tests/jrnl/jtt/options.hpp
Modified:
   store/trunk/cpp/lib/jrnl/data_tok.cpp
   store/trunk/cpp/lib/jrnl/data_tok.hpp
   store/trunk/cpp/lib/jrnl/jcntl.cpp
   store/trunk/cpp/lib/jrnl/nlfh.cpp
   store/trunk/cpp/lib/jrnl/nlfh.hpp
   store/trunk/cpp/lib/jrnl/rrfc.cpp
   store/trunk/cpp/lib/jrnl/rrfc.hpp
   store/trunk/cpp/lib/jrnl/wmgr.cpp
   store/trunk/cpp/lib/jrnl/wmgr.hpp
   store/trunk/cpp/lib/jrnl/wrfc.cpp
   store/trunk/cpp/lib/jrnl/wrfc.hpp
   store/trunk/cpp/tests/jrnl/jtt/Makefile.am
   store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result.cpp
   store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result_agregation.cpp
   store/trunk/cpp/tests/jrnl/jtt/jrnl_instance.cpp
   store/trunk/cpp/tests/jrnl/jtt/main.cpp
   store/trunk/cpp/tests/jrnl/jtt/test_case_result.cpp
   store/trunk/cpp/tests/jrnl/jtt/test_case_result.hpp
   store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.cpp
   store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.hpp
   store/trunk/cpp/tests/jrnl/jtt/test_mgr.cpp
   store/trunk/cpp/tests/jrnl/jtt/test_mgr.hpp
Log:
Fix for BZ 427803: async store error: Timeout waiting for AIOs to complete. Both bugs uncovered in this BZ are fixed. Also change to jtt so that multiple exceptions in one may be captured. Previously the initial exception would be overwritten by a later (often cascade) exception and the cause would be lost.

Modified: store/trunk/cpp/lib/jrnl/data_tok.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/data_tok.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/data_tok.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -49,6 +49,7 @@
     _dsize(0),
     _dblks_written(0),
     _dblks_read(0),
+    _pg_cnt(0),
     _rid(0),
     _xid(),
     _dequeue_rid(0),
@@ -161,6 +162,7 @@
     _dsize = 0;
     _dblks_written = 0;
     _dblks_read = 0;
+    _pg_cnt = 0;
     _rid = 0;
     _xid.clear();
 }

Modified: store/trunk/cpp/lib/jrnl/data_tok.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/data_tok.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/data_tok.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -41,6 +41,7 @@
 }
 }
 
+#include <assert.h>
 #include <pthread.h>
 #include <string>
 #include <sys/types.h>
@@ -100,6 +101,7 @@
         size_t      _dsize;         ///< Data size in bytes
         u_int32_t   _dblks_written; ///< Data blocks read/written
         u_int32_t   _dblks_read;    ///< Data blocks read/written
+        u_int32_t   _pg_cnt;        ///< Page counter - incr for each page containing part of data
         u_int16_t   _fid;           ///< FID containing header of enqueue record
         u_int64_t   _rid;           ///< RID of data set by enqueue operation
         std::string _xid;           ///< XID set by enqueue operation
@@ -136,6 +138,10 @@
         inline void incr_dblocks_read(u_int32_t dblks_read) { _dblks_read += dblks_read; }
         inline void set_dblocks_read(u_int32_t dblks_read) { _dblks_read = dblks_read; }
 
+        inline const u_int32_t pg_cnt() const { return _pg_cnt; }
+        inline const u_int32_t incr_pg_cnt() { return ++_pg_cnt; }
+        inline const u_int32_t decr_pg_cnt() { assert(_pg_cnt != 0); return --_pg_cnt; }
+
         inline const u_int16_t fid() const { return _fid; }
         inline void set_fid(const u_int16_t fid) { _fid = fid; }
         inline const u_int64_t rid() const { return _rid; }

Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -444,10 +444,11 @@
     if (res == RHM_IORES_AIO_WAIT)
     {
         u_int32_t cnt = 0;
-        while (_wmgr.get_events(pmgr::UNUSED) == 0)
+        while (_wmgr.curr_pg_blocked())
         {
+            _wmgr.get_events(pmgr::UNUSED);
             if (cnt++ > MAX_AIO_CMPL_SLEEPS)
-                throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "aio_cmpl_wait");
+                throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "handle_aio_wait");
             ::usleep(AIO_CMPL_SLEEP);
         }
         return true;

Modified: store/trunk/cpp/lib/jrnl/nlfh.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/nlfh.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/nlfh.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -321,14 +321,13 @@
 }
 
 // Debug function
-const std::string&
-nlfh::status_str(std::string& s) const
+const std::string
+nlfh::status_str() const
 {
     std::ostringstream oss;
     oss << "fid=" << _fid << " ws=" << _wr_subm_cnt_dblks << " wc=" << _wr_cmpl_cnt_dblks;
     oss << " rs=" << _rd_subm_cnt_dblks << " rc=" << _rd_cmpl_cnt_dblks;
-    s.assign(oss.str());
-    return s;
+    return oss.str();
 }
 
 // Private functions

Modified: store/trunk/cpp/lib/jrnl/nlfh.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/nlfh.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/nlfh.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -126,7 +126,7 @@
         inline const bool wr_file_rotate() const { return is_wr_full(); }
         
         // Debug aid
-        const std::string& status_str(std::string& s) const;
+        const std::string status_str() const;
 
     protected:
         virtual void open_fh();

Modified: store/trunk/cpp/lib/jrnl/rrfc.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rrfc.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/rrfc.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -89,5 +89,13 @@
     return _fh_arr[pg_index];
 }
 
+const std::string
+rrfc::status_str() const
+{
+    std::ostringstream oss;
+    oss << "rrfc[" << _fh_index << "]: " << _curr_fh->status_str();
+    return oss.str();
+}
+
 } // namespace journal
 } // namespace rhm

Modified: store/trunk/cpp/lib/jrnl/rrfc.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rrfc.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/rrfc.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -130,6 +130,9 @@
         inline const bool file_rotate() const { return _curr_fh->rd_file_rotate(); }
         inline const bool is_wr_aio_outstanding() const
                 { return _curr_fh->wr_aio_outstanding_dblks() > 0; }
+        
+        // Debug aid
+        const std::string status_str() const;
     }; // class rrfc
 
 } // namespace journal

Modified: store/trunk/cpp/lib/jrnl/wmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/wmgr.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -37,6 +37,8 @@
 #include <jrnl/jcntl.hpp>
 #include <jrnl/jerrno.hpp>
 
+#include <iostream> // debug
+
 namespace rhm
 {
 namespace journal
@@ -116,6 +118,9 @@
 {
     if (xid_len)
         assert(xid_ptr != 0);
+    
+    if (_deq_busy || _abort_busy || _commit_busy)
+        return RHM_IORES_BUSY;
 
     if (this_data_len != tot_data_len && !external)
         return RHM_IORES_NOTIMPL;
@@ -124,9 +129,6 @@
     if (res != RHM_IORES_SUCCESS)
         return res;
 
-    if (_deq_busy || _abort_busy || _commit_busy)
-        return RHM_IORES_BUSY;
-
     bool cont = false;
     if (_enq_busy) // If enqueue() exited last time with RHM_IORES_FULL or RHM_IORES_AIO_WAIT
     {
@@ -169,6 +171,8 @@
         _pg_offset_dblks += ret;
         _cached_offset_dblks += ret;
         dtokp->incr_dblocks_written(ret);
+        dtokp->incr_pg_cnt();
+        _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
         // Is the encoding of this record complete?
         if (dtokp->dblocks_written() >= _enq_rec.rec_size_dblks())
@@ -180,7 +184,6 @@
             // long multi-page messages have their token on the page containing the END of the
             // message. AIO callbacks will then only process this token when entire message is
             // enqueued.
-            _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
             _wrfc.incr_enqcnt(dtokp->fid());
 
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
@@ -195,6 +198,8 @@
 
             done = true;
         }
+        else
+            dtokp->set_wstate(data_tok::ENQ_PART);
 
         // Has the file header been written (i.e. write pointers still at 0)?
         if (_wrfc.empty())
@@ -222,7 +227,6 @@
             if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
             {
                 res = RHM_IORES_AIO_WAIT;
-                dtokp->set_wstate(data_tok::ENQ_PART);
                 done = true;
             }
 
@@ -237,11 +241,7 @@
                     if (rfres == RHM_IORES_SUCCESS)
                         cont = true;
                     else
-                    {
-                        // Set last data_tok in page only to state ENQ_PART
-                        dtokp->set_wstate(data_tok::ENQ_PART);
                         done = true;
-                    }
                 }
             }
         }
@@ -257,13 +257,13 @@
     if (xid_len)
         assert(xid_ptr != 0);
 
+    if (_enq_busy || _abort_busy || _commit_busy)
+        return RHM_IORES_BUSY;
+
     iores res = pre_write_check(WMGR_DEQUEUE, dtokp);
     if (res != RHM_IORES_SUCCESS)
         return res;
 
-    if (_enq_busy || _abort_busy || _commit_busy)
-        return RHM_IORES_BUSY;
-
     bool cont = false;
     if (_deq_busy) // If dequeue() exited last time with RHM_IORES_FULL or RHM_IORES_AIO_WAIT
     {
@@ -313,13 +313,14 @@
         _pg_offset_dblks += ret;
         _cached_offset_dblks += ret;
         dtokp->incr_dblocks_written(ret);
+        dtokp->incr_pg_cnt();
+        _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
         // Is the encoding of this record complete?
         if (dtokp->dblocks_written() >= _deq_rec.rec_size_dblks())
         {
             // TODO: Incorrect - must set state to ENQ_CACHED; ENQ_SUBM is set when AIO returns.
             dtokp->set_wstate(data_tok::DEQ_SUBM);
-            _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
             if (xid_len) // If part of transaction, add to transaction map
@@ -342,6 +343,8 @@
 
             done = true;
         }
+        else
+            dtokp->set_wstate(data_tok::DEQ_PART);
 
         // Has the file header been written (i.e. write pointers still at 0)?
         if (_wrfc.empty())
@@ -369,7 +372,6 @@
             if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
             {
                 res = RHM_IORES_AIO_WAIT;
-                dtokp->set_wstate(data_tok::DEQ_PART);
                 done = true;
             }
 
@@ -384,18 +386,13 @@
                     if (rfres == RHM_IORES_SUCCESS)
                         cont = true;
                     else
-                    {
-                        // Set last data_tok in page only to state DEQ_PART
-                        dtokp->set_wstate(data_tok::DEQ_PART);
                         done = true;
-                    }
                 }
             }
         }
     }
     if (dtokp->wstate() >= data_tok::DEQ_SUBM)
         _deq_busy = false;
-
     return res;
 }
 
@@ -453,12 +450,13 @@
         _pg_offset_dblks += ret;
         _cached_offset_dblks += ret;
         dtokp->incr_dblocks_written(ret);
+        dtokp->incr_pg_cnt();
+        _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
         // Is the encoding of this record complete?
         if (dtokp->dblocks_written() >= _txn_rec.rec_size_dblks())
         {
             dtokp->set_wstate(data_tok::ABORT_SUBM);
-            _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
             // Delete this txn from tmap, unlock any locked records in emap
@@ -489,6 +487,8 @@
 
             done = true;
         }
+        else
+            dtokp->set_wstate(data_tok::ABORT_PART);
 
         // Has the file header been written (i.e. write pointers still at 0)?
         if (_wrfc.empty())
@@ -516,7 +516,6 @@
             if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
             {
                 res = RHM_IORES_AIO_WAIT;
-                dtokp->set_wstate(data_tok::ABORT_PART);
                 done = true;
             }
 
@@ -531,18 +530,13 @@
                     if (rfres == RHM_IORES_SUCCESS)
                         cont = true;
                     else
-                    {
-                        // Set last data_tok in page only to state ABORT_PART
-                        dtokp->set_wstate(data_tok::ABORT_PART);
                         done = true;
-                    }
                 }
             }
         }
     }    
     if (dtokp->wstate() >= data_tok::ABORT_SUBM)
         _abort_busy = false;
-    
     return res;
 }
 
@@ -600,12 +594,13 @@
         _pg_offset_dblks += ret;
         _cached_offset_dblks += ret;
         dtokp->incr_dblocks_written(ret);
+        dtokp->incr_pg_cnt();
+        _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
         // Is the encoding of this record complete?
         if (dtokp->dblocks_written() >= _txn_rec.rec_size_dblks())
         {
             dtokp->set_wstate(data_tok::COMMIT_SUBM);
-            _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
 
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
             // Delete this txn from tmap, process records into emap
@@ -632,6 +627,8 @@
 
             done = true;
         }
+        else
+            dtokp->set_wstate(data_tok::COMMIT_PART);
 
         // Has the file header been written (i.e. write pointers still at 0)?
         if (_wrfc.empty())
@@ -659,7 +656,6 @@
             if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
             {
                 res = RHM_IORES_AIO_WAIT;
-                dtokp->set_wstate(data_tok::COMMIT_PART);
                 done = true;
             }
 
@@ -674,18 +670,13 @@
                     if (rfres == RHM_IORES_SUCCESS)
                         cont = true;
                     else
-                    {
-                        // Set last data_tok in page only to state COMMIT_PART
-                        dtokp->set_wstate(data_tok::COMMIT_PART);
                         done = true;
-                    }
                 }
             }
         }
     }    
     if (dtokp->wstate() >= data_tok::COMMIT_SUBM)
         _commit_busy = false;
-    
     return res;
 }
 
@@ -798,62 +789,80 @@
         if (pcbp) // Page writes have pcb
         {
             u_int32_t s = pcbp->_pdtokl->size();
-            std::vector<data_tok*> dtokl(s, 0);
+            std::vector<data_tok*> dtokl;
+            dtokl.reserve(s);
             for (u_int32_t k=0; k<s; k++)
             {
-                data_tok* dtp = pcbp->_pdtokl->at(k);
-                dtokl[k] = dtp;
-                std::set<std::string>::iterator it;
-                switch (dtp->wstate())
+                data_tok* dtokp = pcbp->_pdtokl->at(k);
+                if (dtokp->decr_pg_cnt() == 0)
                 {
-                case data_tok::ENQ_SUBM:
-                    dtp->set_wstate(data_tok::ENQ);
-                    if (dtp->has_xid())
-                        _tmap.set_aio_compl(dtp->xid(), dtp->rid());
-                    break;
-                case data_tok::DEQ_SUBM:
-                    dtp->set_wstate(data_tok::DEQ);
-                    if (dtp->has_xid())
-                        _tmap.set_aio_compl(dtp->xid(), dtp->rid());
-                    break;
-                case data_tok::ABORT_SUBM:
-                    dtp->set_wstate(data_tok::ABORTED);
+                    std::set<std::string>::iterator it;
+                    switch (dtokp->wstate())
+                    {
+                    case data_tok::ENQ_SUBM:
+                        dtokl.push_back(dtokp);
+                        tot_data_toks++;
+                        dtokp->set_wstate(data_tok::ENQ);
+                        if (dtokp->has_xid())
+                            _tmap.set_aio_compl(dtokp->xid(), dtokp->rid());
+                        break;
+                    case data_tok::DEQ_SUBM:
+                        dtokl.push_back(dtokp);
+                        tot_data_toks++;
+                        dtokp->set_wstate(data_tok::DEQ);
+                        if (dtokp->has_xid())
+                            _tmap.set_aio_compl(dtokp->xid(), dtokp->rid());
+                        break;
+                    case data_tok::ABORT_SUBM:
+                        dtokl.push_back(dtokp);
+                        tot_data_toks++;
+                        dtokp->set_wstate(data_tok::ABORTED);
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
-                    it = _txn_pending_set.find(dtp->xid());
-                    if (it == _txn_pending_set.end())
-                    {
-                        std::ostringstream oss;
-                        oss << std::hex << "_txn_pending_set: abort xid=\"" << dtp->xid() << "\"";
-                        throw jexception(jerrno::JERR_MAP_NOTFOUND, oss.str(), "wmgr",
-                                "get_events");
-                    }
-                    _txn_pending_set.erase(it);
+                        it = _txn_pending_set.find(dtokp->xid());
+                        if (it == _txn_pending_set.end())
+                        {
+                            std::ostringstream oss;
+                            oss << std::hex << "_txn_pending_set: abort xid=\"";
+                            oss << dtokp->xid() << "\"";
+                            throw jexception(jerrno::JERR_MAP_NOTFOUND, oss.str(), "wmgr",
+                                    "get_events");
+                        }
+                        _txn_pending_set.erase(it);
 #endif
-                    break;
-                case data_tok::COMMIT_SUBM:
-                    dtp->set_wstate(data_tok::COMMITTED);
+                        break;
+                    case data_tok::COMMIT_SUBM:
+                        dtokl.push_back(dtokp);
+                        tot_data_toks++;
+                        dtokp->set_wstate(data_tok::COMMITTED);
 #if !(defined(RHM_WRONLY) || defined(RHM_RDONLY))
-                    it = _txn_pending_set.find(dtp->xid());
-                    if (it == _txn_pending_set.end())
-                    {
+                        it = _txn_pending_set.find(dtokp->xid());
+                        if (it == _txn_pending_set.end())
+                        {
+                            std::ostringstream oss;
+                            oss << std::hex << "_txn_pending_set: commit xid=\"";
+                            oss << dtokp->xid() << "\"";
+                            throw jexception(jerrno::JERR_MAP_NOTFOUND, oss.str(), "wmgr",
+                                    "get_events");
+                        }
+                        _txn_pending_set.erase(it);
+#endif
+                        break;
+                    case data_tok::ENQ_PART:
+                    case data_tok::DEQ_PART:
+                    case data_tok::ABORT_PART:
+                    case data_tok::COMMIT_PART:
+                        // ignore these
+                        break;
+                    default:
+                        // throw for anything else
                         std::ostringstream oss;
-                        oss << std::hex << "_txn_pending_set: commit xid=\"" << dtp->xid() << "\"";
-                        throw jexception(jerrno::JERR_MAP_NOTFOUND, oss.str(), "wmgr",
+                        oss << "dtok_id=" << dtokp->id() << " dtok_state=" << dtokp->wstate_str();
+                        throw jexception(jerrno::JERR_WMGR_BADDTOKSTATE, oss.str(), "wmgr",
                                 "get_events");
-                    }
-                    _txn_pending_set.erase(it);
-#endif
-                    break;
-                default:
-                    std::ostringstream oss;
-                    oss << "dtok_id=" << dtp->id() << " dtok_state=" << dtp->wstate_str();
-                    throw jexception(jerrno::JERR_WMGR_BADDTOKSTATE, oss.str(), "wmgr",
-                            "get_events");
-                }
-            }
-            tot_data_toks += s;
+                    } // switch
+                } // if
+            } // for
 
-
             // Increment the completed write offset
             // NOTE: We cannot use _wrfc here, as it may have rotated since submitting count.
             // Use stored pointer to nlfh in the pcb instead.
@@ -873,7 +882,6 @@
             file_hdr* fhp = (file_hdr*)iocbp->u.c.buf;
             u_int32_t fid = fhp->_fid;
             nlfh* nlfhp = _wrfc.file_handle(fid);
-//std::cout << "{f*:" << _wrfc.index() << ":" << fid << "," << iocbp << "}" << std::flush;
             nlfhp->add_wr_cmpl_cnt_dblks(JRNL_SBLK_SIZE);
         }        
     }
@@ -962,7 +970,7 @@
                 // Check for enqueue reaching cutoff threshold
                 u_int32_t size_dblks = jrec::size_dblks(enq_rec::rec_size(xidsize, dsize,
                         external));
-                if (_wrfc.enq_threshold(_cached_offset_dblks + size_dblks))
+                if (!_enq_busy && _wrfc.enq_threshold(_cached_offset_dblks + size_dblks))
                     return RHM_IORES_ENQCAPTHRESH;
                 if (!dtokp->is_writable())
                 {
@@ -1058,6 +1066,30 @@
     }
 }
 
+const std::string
+wmgr::status_str() const
+{
+    std::ostringstream oss;
+    oss << "wmgr: pi=" << _pg_index << " pc=" << _pg_cntr;
+    oss << " po=" << _pg_offset_dblks << " aer=" << _aio_evt_rem;
+    oss << " edac:" << (_enq_busy?"T":"F") << (_deq_busy?"T":"F");
+    oss << (_abort_busy?"T":"F") << (_commit_busy?"T":"F");
+    oss << " ps=[";
+    for (int i=0; i<_pages; i++)
+    {
+        switch (_page_cb_arr[i]._state)
+        {
+            case UNUSED:        oss << "-"; break;
+            case IN_USE:        oss << "U"; break;
+            case AIO_PENDING:   oss << "A"; break;
+            case AIO_COMPLETE:  oss << "*"; break;
+            default:            oss << _page_cb_arr[i]._state;
+        }
+    }
+    oss << "] " << _wrfc.status_str();
+    return oss.str();
+}
+
 // static
 
 const char* wmgr::_op_str[] = {"enqueue", "dequeue", "abort", "commit"};

Modified: store/trunk/cpp/lib/jrnl/wmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/wmgr.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -112,6 +112,10 @@
         const iores flush();
         const u_int32_t get_events(page_state state);
         const bool is_txn_synced(const std::string& xid);
+        inline const bool curr_pg_blocked() const { return _page_cb_arr[_pg_index]._state != UNUSED; }
+        
+        // Debug aid
+        const std::string status_str() const;
 
     private:
         void initialize();

Modified: store/trunk/cpp/lib/jrnl/wrfc.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wrfc.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/wrfc.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -128,5 +128,13 @@
     return findex != _fh_index && fhp->enqcnt() > 0;
 }
 
+const std::string
+wrfc::status_str() const
+{
+    std::ostringstream oss;
+    oss << "wrfc[" << _fh_index << "]: " << _curr_fh->status_str();
+    return oss.str();
+}
+
 } // namespace journal
 } // namespace rhm

Modified: store/trunk/cpp/lib/jrnl/wrfc.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wrfc.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/lib/jrnl/wrfc.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -110,6 +110,9 @@
                 { return _curr_fh->wr_aio_outstanding_dblks(); }
         inline const bool file_rotate() const { return _curr_fh->wr_file_rotate(); }
         const bool enq_threshold(const u_int32_t enq_dsize_dblks) const;
+        
+        // Debug aid
+        const std::string status_str() const;
     }; // class wrfc
 
 } // namespace journal

Modified: store/trunk/cpp/tests/jrnl/jtt/Makefile.am
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/Makefile.am	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/Makefile.am	2008-01-23 20:31:53 UTC (rev 1599)
@@ -51,6 +51,7 @@
     jrnl_init_params.cpp \
     jrnl_instance.cpp \
     main.cpp \
+    options.cpp \
     test_case.cpp \
     test_case_result.cpp \
     test_case_result_agregation.cpp \

Modified: store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -37,8 +37,7 @@
     test_case_result tcr(jid);
     BOOST_CHECK_EQUAL(tcr.jid(), jid);
     BOOST_CHECK_EQUAL(tcr.exception(), false);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), "");
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 0U);
     const timespec& ts1 = tcr.start_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, 0);
     BOOST_CHECK_EQUAL(ts1.tv_nsec, 0);
@@ -55,8 +54,7 @@
     const std::string jid("journal id 2");
     test_case_result tcr(jid);
     BOOST_CHECK_EQUAL(tcr.exception(), false);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), "");
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 0U);
     const timespec& ts1 = tcr.start_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, 0);
     BOOST_CHECK_EQUAL(ts1.tv_nsec, 0);
@@ -69,8 +67,7 @@
 
     tcr.set_start_time();
     BOOST_CHECK_EQUAL(tcr.exception(), false);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), "");
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 0U);
     const timespec& ts4 = tcr.start_time();
     BOOST_CHECK(ts4.tv_sec > 0);
     BOOST_CHECK(ts4.tv_nsec > 0);
@@ -84,8 +81,7 @@
     ::usleep(1100000); // 1.1 sec in microseconds
     tcr.set_stop_time();
     BOOST_CHECK_EQUAL(tcr.exception(), false);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), "");
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 0U);
     const timespec& ts7 = tcr.stop_time();
     BOOST_CHECK(ts7.tv_sec > 0);
     BOOST_CHECK(ts7.tv_nsec > 0);
@@ -104,10 +100,10 @@
     const jexception e(err_code, err_msg);
     tcr.set_start_time();
     ::usleep(1100000); // 1.1 sec in microseconds
-    tcr.set_exception(e);
+    tcr.add_exception(e);
     BOOST_CHECK_EQUAL(tcr.exception(), true);
-    BOOST_CHECK_EQUAL(tcr.err_code(), err_code);
-    BOOST_CHECK_EQUAL(tcr.what(), e.what());
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 1U);
+    BOOST_CHECK_EQUAL(tcr[0], e.what());
     const timespec& ts1 = tcr.stop_time();
     BOOST_CHECK(ts1.tv_sec > 0);
     BOOST_CHECK(ts1.tv_nsec > 0);
@@ -124,10 +120,10 @@
     const std::string err_msg = "exception message";
     tcr.set_start_time();
     ::usleep(1100000); // 1.1 sec in microseconds
-    tcr.set_exception(err_msg);
+    tcr.add_exception(err_msg);
     BOOST_CHECK_EQUAL(tcr.exception(), true);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), err_msg);
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 1U);
+    BOOST_CHECK_EQUAL(tcr[0], err_msg);
     const timespec& ts1 = tcr.stop_time();
     BOOST_CHECK(ts1.tv_sec > 0);
     BOOST_CHECK(ts1.tv_nsec > 0);
@@ -144,10 +140,10 @@
     const char* err_msg = "exception message";
     tcr.set_start_time();
     ::usleep(1100000); // 1.1 sec in microseconds
-    tcr.set_exception(err_msg);
+    tcr.add_exception(err_msg);
     BOOST_CHECK_EQUAL(tcr.exception(), true);
-    BOOST_CHECK_EQUAL(tcr.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcr.what(), err_msg);
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 1U);
+    BOOST_CHECK_EQUAL(tcr[0], err_msg);
     const timespec& ts1 = tcr.stop_time();
     BOOST_CHECK(ts1.tv_sec > 0);
     BOOST_CHECK(ts1.tv_nsec > 0);
@@ -166,10 +162,10 @@
     const jexception e(err_code, err_msg);
     tcr.set_start_time();
     ::usleep(1100000); // 1.1 sec in microseconds
-    tcr.set_exception(e, false);
+    tcr.add_exception(e, false);
     BOOST_CHECK_EQUAL(tcr.exception(), true);
-    BOOST_CHECK_EQUAL(tcr.err_code(), err_code);
-    BOOST_CHECK_EQUAL(tcr.what(), e.what());
+    BOOST_CHECK_EQUAL(tcr.exception_count(), 1U);
+    BOOST_CHECK_EQUAL(tcr[0], e.what());
     const timespec& ts1 = tcr.stop_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, 0);
     BOOST_CHECK_EQUAL(ts1.tv_nsec, 0);

Modified: store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result_agregation.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result_agregation.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/_ut_test_case_result_agregation.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -45,8 +45,7 @@
     BOOST_CHECK_EQUAL(tcra.tc_average_mode(), true);
     BOOST_CHECK_EQUAL(tcra.jid(), "Average");
     BOOST_CHECK_EQUAL(tcra.exception(), false);
-    BOOST_CHECK_EQUAL(tcra.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcra.what(), "");
+    BOOST_CHECK_EQUAL(tcra.exception_count(), 0U);
     const timespec& ts1 = tcra.start_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, 0);
     BOOST_CHECK_EQUAL(ts1.tv_nsec, 0);
@@ -65,8 +64,7 @@
     BOOST_CHECK_EQUAL(tcra.tc_average_mode(), false);
     BOOST_CHECK_EQUAL(tcra.jid(), jid);
     BOOST_CHECK_EQUAL(tcra.exception(), false);
-    BOOST_CHECK_EQUAL(tcra.err_code(), u_int32_t(0));
-    BOOST_CHECK_EQUAL(tcra.what(), "");
+    BOOST_CHECK_EQUAL(tcra.exception_count(), 0U);
     const timespec& ts1 = tcra.start_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, 0);
     BOOST_CHECK_EQUAL(ts1.tv_nsec, 0);
@@ -86,10 +84,10 @@
     test_case_result::shared_ptr tcrp3 = make_result("jid1",   0,  15,   5,   2, 555555555L);
     test_case_result::shared_ptr tcrp4 = make_result("jid2", 100, 100, 100, 100, 323232324L);
     test_case_result::shared_ptr tcrp5 = make_result("jid1",   5,   0,   0,   0,       100L);
-    tcrp5->set_exception(std::string("error 1"), false);
+    tcrp5->add_exception(std::string("error 1"), false);
     test_case_result::shared_ptr tcrp6 = make_result("jid3",   0,   5,   0,   0,       100L);
     jexception e(0x123, "exception 2");
-    tcrp6->set_exception(e, false);
+    tcrp6->add_exception(e, false);
     test_case_result::shared_ptr tcrp7 = make_result("jid1",   0,   0,   0,   0,         0L);
     test_case_result::shared_ptr tcrp8 = make_result("jid1", 200, 100, 300,  12, 323232224L);
 
@@ -120,10 +118,10 @@
     test_case_result::shared_ptr tcrp3 = make_result("jid3",   0,  15,   5,   2, 555555555L);
     test_case_result::shared_ptr tcrp4 = make_result("jid4", 100, 100, 100, 100, 323232324L);
     test_case_result::shared_ptr tcrp5 = make_result("jid5",   5,   0,   0,   0,       100L);
-    tcrp5->set_exception(std::string("error 1"), false);
+    tcrp5->add_exception(std::string("error 1"), false);
     test_case_result::shared_ptr tcrp6 = make_result("jid6",   0,   5,   0,   0,       100L);
     jexception e(0x123, "exception 2");
-    tcrp6->set_exception(e, false);
+    tcrp6->add_exception(e, false);
     test_case_result::shared_ptr tcrp7 = make_result("jid7",   0,   0,   0,   0,         0L);
     test_case_result::shared_ptr tcrp8 = make_result("jid8", 200, 100, 300,  12, 222222022L);
 
@@ -158,7 +156,7 @@
     BOOST_CHECK_EQUAL(tcra.num_deq(), num_deq);
     BOOST_CHECK_EQUAL(tcra.num_read(), num_reads);
     BOOST_CHECK_EQUAL(tcra.num_results(), num_results);
-    BOOST_CHECK_EQUAL(tcra.num_exceptions(), num_exceptions);
+    BOOST_CHECK_EQUAL(tcra.exception_count(), num_exceptions);
     BOOST_CHECK_EQUAL(tcra.exception(), num_exceptions > 0);
     const timespec& ts1 = tcra.test_time();
     BOOST_CHECK_EQUAL(ts1.tv_sec, secs);

Modified: store/trunk/cpp/tests/jrnl/jtt/jrnl_instance.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/jrnl_instance.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/jrnl_instance.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -28,6 +28,8 @@
 #include <jrnl/data_tok.hpp>
 #include <jrnl/jerrno.hpp>
 
+#include <iostream>
+
 #define SLEEP_US        1000 // 1 ms
 #define MAX_SLEEP_CNT   2000 // 2 sec max
 
@@ -81,6 +83,9 @@
         _tcp = tcp;
         _recover_mode = recover_mode;
         _keep_jrnls = keep_jrnls;
+        _dtok_master_enq_list.clear();
+        _dtok_master_txn_list.clear();
+        _dtok_deq_list.clear();
 
         if (_recover_mode)
         {
@@ -105,9 +110,9 @@
         test_case_result::shared_ptr p(new test_case_result(_jpp->jid()));
         _tcrp = p;
     }
-    catch (const rhm::journal::jexception& e) { _tcrp->set_exception(e); }
-    catch (const std::exception& e) { _tcrp->set_exception(e.what()); }
-    catch (...) { _tcrp->set_exception("Unknown exception"); }
+    catch (const rhm::journal::jexception& e) { _tcrp->add_exception(e); }
+    catch (const std::exception& e) { _tcrp->add_exception(e.what()); }
+    catch (...) { _tcrp->add_exception("Unknown exception"); }
 }
 
 void
@@ -130,9 +135,9 @@
         stop(true);
         _tcrp->set_stop_time();
     }
-    catch (const rhm::journal::jexception& e) { _tcrp->set_exception(e); }
-    catch (const std::exception& e) { _tcrp->set_exception(e.what()); }
-    catch (...) { _tcrp->set_exception("Unknown exception"); }
+    catch (const rhm::journal::jexception& e) { _tcrp->add_exception(e); }
+    catch (const std::exception& e) { _tcrp->add_exception(e.what()); }
+    catch (...) { _tcrp->add_exception("Unknown exception"); }
     _tcrp->set_stop_time();
     _tcp->add_result(_tcrp);
     
@@ -185,7 +190,7 @@
                     std::ostringstream oss;
                     oss << "ERROR: Timeout waiting for journal \"" << _jid;
                     oss << "\" to empty.";
-                    _tcrp->set_exception(oss.str());
+                    _tcrp->add_exception(oss.str());
                 }
                 else
                     ::usleep(SLEEP_US); // 1ms
@@ -195,15 +200,15 @@
                 std::ostringstream oss;
                 oss << "ERROR: enqueue operation in journal \"" << _jid << "\" returned ";
                 oss << rhm::journal::iores_str(res) << ".";
-                _tcrp->set_exception(oss.str());
+                _tcrp->add_exception(oss.str());
             }
             
         }
         flush();
     }
-    catch (const rhm::journal::jexception& e) { _tcrp->set_exception(e); }
-    catch (const std::exception& e) { _tcrp->set_exception(e.what()); }
-    catch (...) { _tcrp->set_exception("Unknown exception"); }
+    catch (const rhm::journal::jexception& e) { _tcrp->add_exception(e); }
+    catch (const std::exception& e) { _tcrp->add_exception(e.what()); }
+    catch (...) { _tcrp->add_exception("Unknown exception"); }
 }
 
 void
@@ -224,7 +229,7 @@
                         oss << "ERROR: Timeout waiting for AIO in journal \"" << _jid;
                         oss << "\": num_enq=" << _tcp->num_msgs();
                         oss << " num_deq=" << _tcrp->num_deq();
-                        _tcrp->set_exception(oss.str());
+                        _tcrp->add_exception(oss.str());
                     }
                     get_wr_events();
                     ::usleep(SLEEP_US); // 1ms
@@ -254,7 +259,7 @@
                         std::ostringstream oss;
                         oss << "ERROR: dequeue operation in journal \"" << _jid;
                         oss << "\" returned " << rhm::journal::iores_str(res) << ".";
-                        _tcrp->set_exception(oss.str());
+                        _tcrp->add_exception(oss.str());
                     }
                     sleep_cnt = 0U;
                 }
@@ -262,9 +267,9 @@
             flush();
         }
     }
-    catch (const rhm::journal::jexception& e) { _tcrp->set_exception(e); }
-    catch (const std::exception& e) { _tcrp->set_exception(e.what()); }
-    catch (...) { _tcrp->set_exception("Unknown exception"); }
+    catch (const rhm::journal::jexception& e) { _tcrp->add_exception(e); }
+    catch (const std::exception& e) { _tcrp->add_exception(e.what()); }
+    catch (...) { _tcrp->add_exception("Unknown exception"); }
 }
 
 void
@@ -295,7 +300,7 @@
             std::ostringstream oss;
             oss << "ERROR: " << (commit ? "commit" : "abort") << " operation in journal \"";
             oss << _jid << "\" returned " << rhm::journal::iores_str(res) << ".";
-            _tcrp->set_exception(oss.str());
+            _tcrp->add_exception(oss.str());
         }
     }
 }

Modified: store/trunk/cpp/tests/jrnl/jtt/main.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/main.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/main.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -24,8 +24,8 @@
 #include "config.hpp"
 #include "test_mgr.hpp"
 
-#include <boost/program_options.hpp>
 #include <iostream>
+#include "options.hpp"
 #include <signal.h>
 
 namespace po = boost::program_options;
@@ -35,90 +35,17 @@
     ::signal(SIGINT, rhm::jtt::test_mgr::signal_handler);
     ::signal(SIGTERM, rhm::jtt::test_mgr::signal_handler);
 
-    unsigned num_jrnls;
-    std::string test_case_csv_file_name;
-    bool jrnl_format_chk = false;
-    bool reuse_instance = false;
-    bool recover_mode = false;
-    bool random_test_order = false;
-    bool repeat_flag = false;
-    bool keep_jrnls = false;
-
     std::cout << PACKAGE_NAME << " v." << VERSION << std::endl;
 
     std::ostringstream oss;
     oss << PACKAGE_NAME << " options";
-    po::options_description od(oss.str());
-    od.add_options()
-            ("help", "This help message")
-            ("num-jrnls", po::value<unsigned>(&num_jrnls)->default_value(1),
-                    "Number of simultaneous journal instances to test")
-            ("csv", po::value<std::string>(&test_case_csv_file_name)->default_value("jtt.csv"),
-                    "CSV file containing test cases")
-            ("jrnl-format-chk", po::value<bool>(&jrnl_format_chk)->zero_tokens(),
-                    "If true, will check the format of each journal file")
-            ("reuse-instance", po::value<bool>(&reuse_instance)->zero_tokens(),
-                    "If true, will cause first journal instance to be reused for all test cases")
-            ("recover-mode", po::value<bool>(&recover_mode)->zero_tokens(),
-                    "If true, will cause the journal from the previous test to be recovered")
-            ("random-test-order", po::value<bool>(&random_test_order)->zero_tokens(),
-                    "If true, will randomize the order of the tests in the csv file")
-            ("repeat", po::value<bool>(&repeat_flag)->zero_tokens(),
-                    "If true, will repeat tests in csv file indefinitely")
-            ("keep-jrnls", po::value<bool>(&keep_jrnls)->zero_tokens(),
-                    "If true, will keep all test journals in backup dirs");
-    po::variables_map vmap;
-    try
-    {
-        po::store(po::parse_command_line(argc, argv, od), vmap);
-        po::notify(vmap);
-    }
-    catch (const std::exception& e)
-    {
-        std::cout << "ERROR: " << e.what() << std::endl;
-        std::cout << od << std::endl;
-        return 1;
-    }
-    if (vmap.count("help"))
-    {
-        std::cout << od << std::endl;
-        return 0;
-    }
-    if (num_jrnls == 0)
-    {
-        std::cout << "ERROR: num_jrnls must be 1 or more." << std::endl;
-        std::cout << od << std::endl;
-        return 1;
-    }
-    if (repeat_flag && keep_jrnls)
-    {
-        std::string resp;
-        std::cout << "WARNING: repeat and keep_jrnls: Monitor disk usage as test journals will accumulate." << std::endl;
-        std::cout << "Continue? <y/n> ";
-        std::cin >> resp;
-        if (resp.size() == 1)
-        {
-            if (resp[0] != 'y' && resp[0] != 'Y')
-                return 0;
-        }
-        else if (resp.size() == 3) // any combo of lower- and upper-case
-        {
-            if (resp[0] != 'y' && resp[0] != 'Y')
-                return 0;
-            if (resp[1] != 'e' && resp[1] != 'E')
-                return 0;
-            if (resp[2] != 's' && resp[2] != 'S')
-                return 0;
-        }
-        else
-            return 0;
-    }
+    rhm::jtt::options opts(oss.str());
+    if (opts.validate(argc, argv)) return 1;
 
     try
     {
-        rhm::jtt::test_mgr tm(num_jrnls);
-        tm.run(test_case_csv_file_name, jrnl_format_chk, reuse_instance, recover_mode,
-                random_test_order, repeat_flag, keep_jrnls);
+        rhm::jtt::test_mgr tm(opts);
+        tm.run();
     }
     catch (const std::exception& e)
     {

Added: store/trunk/cpp/tests/jrnl/jtt/options.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/options.cpp	                        (rev 0)
+++ store/trunk/cpp/tests/jrnl/jtt/options.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -0,0 +1,139 @@
+/**
+* Copyright 2008 Red Hat, Inc.
+*
+* This file is part of Red Hat Messaging.
+*
+* Red Hat Messaging is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+* USA
+*
+* The GNU Lesser General Public License is available in the file COPYING.
+*/
+
+#include "options.hpp"
+
+#include <iostream>
+
+namespace po = boost::program_options;
+
+namespace rhm
+{
+namespace jtt
+{
+
+options::options(std::string opt_title):
+    _options_descr(opt_title),
+    jrnl_format_chk(false),
+    reuse_instance(false),
+    recover_mode(false),
+    repeat_flag(false),
+    keep_jrnls(false)
+{
+    _options_descr.add_options()
+            ("help,h", "This help message")
+            ("num-jrnls", po::value<unsigned>(&num_jrnls)->default_value(1),
+                    "Number of simultaneous journal instances to test")
+            ("csv-file,c",
+                    po::value<std::string>(&test_case_csv_file_name)->default_value("jtt.csv"),
+                    "CSV file containing test cases")
+            ("jrnl-format-chk", po::value<bool>(&jrnl_format_chk)->zero_tokens(),
+                    "If true, will check the format of each journal file")
+            ("reuse-instance", po::value<bool>(&reuse_instance)->zero_tokens(),
+                    "If true, will cause first journal instance to be reused for all test cases")
+            ("recover-mode", po::value<bool>(&recover_mode)->zero_tokens(),
+                    "If true, will cause the journal from the previous test to be recovered")
+            ("repeat", po::value<bool>(&repeat_flag)->zero_tokens(),
+                    "If true, will repeat tests in csv file indefinitely")
+            ("keep-jrnls", po::value<bool>(&keep_jrnls)->zero_tokens(),
+                    "If true, will keep all test journals in backup dirs");
+}
+
+const bool
+options::validate(int argc, char** argv) // return true if error, false if ok
+{
+    try
+    {
+        po::store(po::parse_command_line(argc, argv, _options_descr), _vmap);
+        po::notify(_vmap);
+    }
+    catch (const std::exception& e)
+    {
+        std::cout << "ERROR: " << e.what() << std::endl;
+        return usage();
+    }
+    if (_vmap.count("help"))
+        return usage();
+    if (num_jrnls == 0)
+    {
+        std::cout << "ERROR: num_jrnls must be 1 or more." << std::endl;
+        return usage();
+    }
+    if (repeat_flag && keep_jrnls)
+    {
+        std::string resp;
+        std::cout << "WARNING: repeat and keep-jrnls: Monitor disk usage as test journals will"
+                " accumulate." << std::endl;
+        std::cout << "Continue? <y/n> ";
+        std::cin >> resp;
+        if (resp.size() == 1)
+        {
+            if (resp[0] != 'y' && resp[0] != 'Y')
+                return true;
+        }
+        else if (resp.size() == 3) // any combo of lower- and upper-case
+        {
+            if (resp[0] != 'y' && resp[0] != 'Y')
+                return true;
+            if (resp[1] != 'e' && resp[1] != 'E')
+                return true;
+            if (resp[2] != 's' && resp[2] != 'S')
+                return true;
+        }
+        else
+            return true;
+    }
+    return false;
+}
+
+const bool
+options::usage() const
+{
+    std::cout << _options_descr << std::endl;
+    return true;
+}
+
+const void
+options::print_flags() const
+{
+    if (jrnl_format_chk || reuse_instance || recover_mode || repeat_flag || keep_jrnls)
+    {
+        std::cout << "Options:";
+        // TODO: Get flag options and their strings directly from _options_descr.
+        if (jrnl_format_chk)
+            std::cout << " jrnl-format-chk";
+        if (reuse_instance)
+            std::cout << " reuse-instance";
+        if (recover_mode)
+            std::cout << " recover-mode";
+        if (repeat_flag)
+            std::cout << " repeat-flag";
+        if (keep_jrnls)
+            std::cout << " keep-jrnls";
+        std::cout << std::endl;
+    }
+    std::cout << std::endl;
+}
+    
+} // namespace jtt
+} // namespace rhm

Added: store/trunk/cpp/tests/jrnl/jtt/options.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/options.hpp	                        (rev 0)
+++ store/trunk/cpp/tests/jrnl/jtt/options.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -0,0 +1,57 @@
+/**
+* Copyright 2008 Red Hat, Inc.
+*
+* This file is part of Red Hat Messaging.
+*
+* Red Hat Messaging is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+* USA
+*
+* The GNU Lesser General Public License is available in the file COPYING.
+*/
+
+#ifndef rhm_jtt_options_hpp
+#define rhm_jtt_options_hpp
+
+#include <boost/program_options.hpp>
+
+namespace rhm
+{
+namespace jtt
+{
+
+    struct options
+    {
+        boost::program_options::options_description _options_descr;
+        boost::program_options::variables_map _vmap;
+
+        // Add options here
+        unsigned num_jrnls;
+        std::string test_case_csv_file_name;
+        bool jrnl_format_chk;
+        bool reuse_instance;
+    	bool recover_mode;
+        bool repeat_flag;
+        bool keep_jrnls;
+
+        options(std::string opt_title);
+        const bool validate(int argc, char** argv); // return true if error, false if ok
+        const bool usage() const; // return true
+        const void print_flags() const;
+    };
+
+} // namespace jtt
+} // namespace rhm
+
+#endif // ifndef rhm_jtt_options_hpp

Modified: store/trunk/cpp/tests/jrnl/jtt/test_case_result.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_case_result.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_case_result.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -36,8 +36,8 @@
         _num_enq(0),
         _num_deq(0),
         _num_read(0),
-        _exception_flag(false),
-        _err_code(0)
+        _stopped(false),
+        _exception_list()
 {
     _start_time.tv_sec = 0;
     _start_time.tv_nsec = 0;
@@ -62,31 +62,36 @@
 }
 
 void
-test_case_result::set_exception(const journal::jexception& e, const bool set_stop_time_flag)
+test_case_result::add_exception(const journal::jexception& e, const bool set_stop_time_flag)
 {
-    if (set_stop_time_flag)
+    if (!_stopped && set_stop_time_flag)
+    {
         set_stop_time();
-    _exception_flag = true;
-    _err_code = e.err_code();
-    _exception_str = e.what();
+        _stopped = true;
+    }
+    _exception_list.push_back(e.what());
 }
 
 void
-test_case_result::set_exception(const std::string& err_str, const bool set_stop_time_flag)
+test_case_result::add_exception(const std::string& err_str, const bool set_stop_time_flag)
 {
-    if (set_stop_time_flag)
+    if (!_stopped && set_stop_time_flag)
+    {
         set_stop_time();
-    _exception_flag = true;
-    _exception_str = err_str;
+        _stopped = true;
+    }
+    _exception_list.push_back(err_str);
 }
 
 void
-test_case_result::set_exception(const char* err_str, const bool set_stop_time_flag)
+test_case_result::add_exception(const char* err_str, const bool set_stop_time_flag)
 {
-    if (set_stop_time_flag)
+    if (!_stopped && set_stop_time_flag)
+    {
         set_stop_time();
-    _exception_flag = true;
-    _exception_str = err_str;
+        _stopped = true;
+    }
+    _exception_list.push_back(err_str);
 }
 
 void
@@ -101,9 +106,7 @@
     _stop_time.tv_nsec = 0;
     _test_time.tv_sec = 0;
     _test_time.tv_nsec = 0;
-    _exception_flag = false;
-    _err_code = 0;
-    _exception_str = "";
+    _exception_list.clear();
 }
 
 const std::string
@@ -114,8 +117,8 @@
     {
         oss << _jid << ":";
         oss << str_summary();
-        if (_exception_flag)
-            oss << "; fail: " << _exception_str << std::endl;
+        if (_exception_list.size())
+            oss << "; fail: " << _exception_list[0] << std::endl;
         else
             oss << "; ok" << std::endl;
     }
@@ -123,8 +126,8 @@
     {
         oss << "--- Journal instance: jid=\"" << _jid << "\" ---" << std::endl;
         oss << str_full();
-        if (_exception_flag)
-            oss << "       exception/error:" << _exception_str << std::endl;
+        if (_exception_list.size())
+            oss << "       exception/error:" << _exception_list[0] << std::endl;
     }
     return oss.str();
 }
@@ -132,68 +135,70 @@
 const std::string
 test_case_result::str_full() const
 {
-    double t = _test_time.tv_sec + (_test_time.tv_nsec/1e9);
+    const double t = _test_time.tv_sec + (_test_time.tv_nsec/1e9);
+    const bool no_exception = _exception_list.empty();
     std::ostringstream oss;
     oss.setf(std::ios::fixed, std::ios::floatfield);
     oss.precision(2);
-    if (!_exception_flag)
+    if (no_exception)
     {
         oss.precision(6);
         oss << "       total test time: " << t << "s" << std::endl;
     }
     oss.precision(3);
     oss << " total number enqueues: " << _num_enq;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_enq / t) << " enq/sec)";
     oss << std::endl;
     oss << " total number dequeues: " << _num_deq;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_deq / t) << " deq/sec)";
     oss << std::endl;
     oss << "total write operations: " << (_num_enq + _num_deq);
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << ((_num_enq + _num_deq) / t) << " wrops/sec)";
     oss << std::endl;
     oss << "    total number reads: " << _num_read;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_read / t) << " rd/sec)";
     oss << std::endl;
     oss << "      total operations: " << (_num_enq + _num_deq + _num_read);
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << ((_num_enq + _num_deq + _num_read) / t) << " ops/sec)";
     oss << std::endl;
-    oss << "        overall result: " << (_exception_flag ? "*** FAIL ***" : "PASS") << std::endl;
+    oss << "        overall result: " << (no_exception ? "PASS" : "*** FAIL ***") << std::endl;
     return oss.str();
 }
 
 const std::string
 test_case_result::str_summary() const
 {
-    double t = _test_time.tv_sec + (_test_time.tv_nsec/1e9);
+    const double t = _test_time.tv_sec + (_test_time.tv_nsec/1e9);
+    const bool no_exception = _exception_list.empty();
     std::ostringstream oss;
     oss.setf(std::ios::fixed, std::ios::floatfield);
-    if (_exception_flag)
-        oss << " exception";
-    else
+    if (no_exception)
     {
         oss.precision(6);
         oss << " t=" << t << "s;";
     }
+    else
+        oss << " exception";
     oss.precision(3);
     oss << " enq=" << _num_enq;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_enq / t) << ")";
     oss << "; deq=" << _num_deq;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_deq / t) << ")";
     oss << "; wr=" << (_num_enq + _num_deq);
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << ((_num_enq + _num_deq) / t) << ")";
     oss << "; rd=" << _num_read;
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << (_num_read / t) << ")";
     oss << "; tot=" << (_num_enq + _num_deq + _num_read);
-    if (!_exception_flag)
+    if (no_exception)
         oss << " (" << ((_num_enq + _num_deq + _num_read) / t) << ")";
     return oss.str();
 }

Modified: store/trunk/cpp/tests/jrnl/jtt/test_case_result.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_case_result.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_case_result.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -25,6 +25,7 @@
 #define rhm_jtt_test_case_result_hpp
 
 #include <boost/shared_ptr.hpp>
+#include <deque>
 #include <jrnl/jexception.hpp>
 #include <string>
 
@@ -38,6 +39,9 @@
     public:
         typedef boost::shared_ptr<test_case_result> shared_ptr;
 
+        typedef std::deque<std::string> elist;
+        typedef elist::const_iterator elist_citr;
+
     protected:
         std::string _jid;
         u_int32_t _num_enq;
@@ -45,12 +49,10 @@
         u_int32_t _num_read;
         timespec _start_time;
         timespec _stop_time;
+        bool _stopped;
         timespec _test_time;
+        elist _exception_list;
 
-        bool _exception_flag;
-        u_int32_t _err_code;
-        std::string _exception_str;
-
     public:
         test_case_result(const std::string& jid);
         virtual ~test_case_result();
@@ -73,12 +75,14 @@
         inline const timespec& test_time() const { return _test_time; }
         const std::string test_time_str() const;
 
-        inline const bool exception() const { return _exception_flag; }
-        inline const u_int32_t err_code() const { return _err_code; }
-        inline const std::string& what() const { return _exception_str; }
-        void set_exception(const journal::jexception& e, const bool set_stop_time_flag = true);
-        void set_exception(const std::string& err_str, const bool set_stop_time_flag = true);
-        void set_exception(const char* err_str, const bool set_stop_time_flag = true);
+        void add_exception(const journal::jexception& e, const bool set_stop_time_flag = true);
+        void add_exception(const std::string& err_str, const bool set_stop_time_flag = true);
+        void add_exception(const char* err_str, const bool set_stop_time_flag = true);
+        inline const bool exception() const { return _exception_list.size() > 0; }
+        inline const unsigned exception_count() const { return _exception_list.size(); }
+        inline elist_citr begin() { return _exception_list.begin(); }
+        inline elist_citr end() { return _exception_list.end(); }
+        inline const std::string& operator[](unsigned i) { return _exception_list[i]; }
         
         void clear();
         const std::string str(const bool summary) const;

Modified: store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -34,16 +34,14 @@
 test_case_result_agregation::test_case_result_agregation():
         test_case_result("Average"),
         _tc_average(true),
-        _rlist(),
-        _elist()
+        _rlist()
 {
 }
 
 test_case_result_agregation::test_case_result_agregation(const std::string& jid):
         test_case_result(jid),
         _tc_average(false),
-        _rlist(),
-        _elist()
+        _rlist()
 {}
 
 test_case_result_agregation::~test_case_result_agregation()
@@ -58,11 +56,7 @@
         _num_deq += tcrp->num_deq();
         _num_read += tcrp->num_read();
         add_test_time(tcrp->test_time());
-        if (tcrp->exception())
-        {
-            _exception_flag = true;
-            _elist.push_back(tcrp->what());
-        }
+        _exception_list.insert(_exception_list.end(), tcrp->begin(), tcrp->end());
         _rlist.push_back(tcrp);
     }
 }
@@ -72,7 +66,6 @@
 {
     test_case_result::clear();
     _rlist.clear();
-    _elist.clear();
 }
 
 const std::string
@@ -101,16 +94,16 @@
     else
         oss << "Average for jid=\"" << _jid << "\":" << std::endl;
     oss << "  total number results: " << _rlist.size() << std::endl;
-    oss << "     number exceptions: " << _elist.size() << " (" <<
-            (100.0 * _rlist.size() / _elist.size()) << "%)" << std::endl;
+    oss << "     number exceptions: " << _exception_list.size() << " (" <<
+            (100.0 * _rlist.size() / _exception_list.size()) << "%)" << std::endl;
 
     oss << test_case_result::str_full();
 
-    if (_exception_flag && _elist.size())
+    if (_exception_list.size())
     {
         unsigned n = 0;
         oss << "List of exceptions/errors:" << std::endl;
-        for (err_list_citr i = _elist.begin(); i != _elist.end(); i++, n++)
+        for (elist_citr i = _exception_list.begin(); i != _exception_list.end(); i++, n++)
             oss << "  " << n << ". " << (*i) << std::endl;
     }
 
@@ -136,20 +129,20 @@
 
     oss << test_case_result::str_summary();
 
-    if (_exception_flag && _elist.size())
+    if (_exception_list.size())
     {
         if (_tc_average)
-            oss << " fail: " << _elist.size() << " exception" << (_elist.size()>1?"s":"") <<
-                    std::endl;
+            oss << " fail: " << _exception_list.size() << " exception"
+                << (_exception_list.size()>1?"s":"") << std::endl;
         else
         {
-            if (_elist.size() == 1)
-                oss << " fail: " << *_elist.begin() << std::endl;
+            if (_exception_list.size() == 1)
+                oss << " fail: " << *_exception_list.begin() << std::endl;
             else
             {
                 oss << std::endl;
                 unsigned n = 0;
-                for (err_list_citr i = _elist.begin(); i != _elist.end(); i++, n++)
+                for (elist_citr i = _exception_list.begin(); i != _exception_list.end(); i++, n++)
                     oss << "    " << n << ". " << (*i) << std::endl;
             }
         }

Modified: store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_case_result_agregation.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -41,13 +41,9 @@
         typedef std::vector<test_case_result::shared_ptr> tcrp_list;
         typedef tcrp_list::const_iterator tcrp_list_citr;
 
-        typedef std::vector<std::string> err_list;
-        typedef err_list::const_iterator err_list_citr;
-
     private:
         bool _tc_average;
         tcrp_list _rlist;
-        err_list _elist;
 
     public:
         test_case_result_agregation(); // used for average across jrnl instances
@@ -62,9 +58,6 @@
         inline tcrp_list_citr rlist_end() const { return _rlist.end(); }
         inline const test_case_result::shared_ptr& operator[](unsigned i) const
                 { return _rlist[i]; }
-        inline const u_int32_t num_exceptions() const { return _elist.size(); }
-        inline err_list_citr elist_begin() const { return _elist.begin(); }
-        inline err_list_citr elist_end() const { return _elist.end(); }
 
         void clear();
         const std::string str(const bool last_only, const bool summary) const;

Modified: store/trunk/cpp/tests/jrnl/jtt/test_mgr.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_mgr.cpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_mgr.cpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -31,20 +31,18 @@
 namespace jtt
 {
 
-test_mgr::test_mgr(const unsigned num_jrnls):
+test_mgr::test_mgr(options& opts):
         _ji_list(),
-        _num_jrnls(num_jrnls)
+        _opts(opts)
 {
-    std::cout << "Number of journals: " << _num_jrnls << std::endl;
+    std::cout << "Number of journals: " << _opts.num_jrnls << std::endl;
 }
 
 test_mgr::~test_mgr()
 {}
 
 void
-test_mgr::run(const std::string& tc_csv_file_name, const bool jrnl_format_chk,
-        const bool reuse_instance, const bool recover_mode, const bool random_test_order,
-        const bool repeat_flag, const bool keep_jrnls)
+test_mgr::run()
 {
     // TODO: complete tidy-up of non-summary (verbose) results, then pull through
     // a command-line summary to control this.
@@ -53,32 +51,16 @@
     //       defualt: none of these, similar to current summary = true version.
     const bool summary = true;
 
-    std::cout << "CSV file: \"" << tc_csv_file_name << "\"";
-    test_case_set tcs(tc_csv_file_name);
+    std::cout << "CSV file: \"" << _opts.test_case_csv_file_name << "\"";
+    test_case_set tcs(_opts.test_case_csv_file_name);
     const unsigned num_test_cases = tcs.size();
     if (num_test_cases)
+    {
         std::cout << " (containing " << tcs.size() << " test cases)" << std::endl;
+        _opts.print_flags();
+    }
     else
         std::cout << " (WARNING: This CSV file is empty or does not exist.)" << std::endl;
-    if (jrnl_format_chk || reuse_instance || recover_mode || random_test_order || repeat_flag ||
-            keep_jrnls)
-    {
-        std::cout << "Options:";
-        if (jrnl_format_chk)
-            std::cout << " jrnl_format_chk";
-        if (reuse_instance)
-            std::cout << " reuse_instance";
-        if (recover_mode)
-            std::cout << " recover_mode";
-        if (random_test_order)
-            std::cout << " random_test_order";
-        if (repeat_flag)
-            std::cout << " repeat_flag";
-        if (keep_jrnls)
-            std::cout << " keep_jrnls";
-        std::cout << std::endl;
-    }
-    std::cout << std::endl;
 
     do
     {
@@ -90,15 +72,15 @@
                         (*tci)->comment() << "\"" << std::endl;
             else
                 std::cout << (*tci)->str() << std::endl;
-            if (!reuse_instance || _ji_list.empty())
+            if (!_opts.reuse_instance || _ji_list.empty())
                 initialize_jrnls();
             for (ji_list_citr jii=_ji_list.begin(); jii!=_ji_list.end(); jii++)
-                (*jii)->init_tc(*tci, recover_mode, keep_jrnls);
+                (*jii)->init_tc(*tci, _opts.recover_mode, _opts.keep_jrnls);
             for (ji_list_citr jii=_ji_list.begin(); jii!=_ji_list.end(); jii++)
                 (*jii)->run_tc();
             for (ji_list_citr jii=_ji_list.begin(); jii!=_ji_list.end(); jii++)
                 (*jii)->tc_wait_compl();
-            if (jrnl_format_chk)
+            if (_opts.jrnl_format_chk)
             {
                 for (ji_list_citr jii=_ji_list.begin(); jii!=_ji_list.end(); jii++)
                 {
@@ -107,7 +89,7 @@
                     oss << "jfile_chk.py -q";
                     oss << " -d " << jpp->jdir();
                     oss << " -b " << jpp->base_filename();
-                    oss << " -c" << tc_csv_file_name;
+                    oss << " -c" << _opts.test_case_csv_file_name;
                     oss << " -t" << (*tci)->test_case_num();
                     if (system(oss.str().c_str()))
                     {
@@ -118,11 +100,11 @@
                 }
             }
             print_results(*tci, summary);
-            if (_abort || (!repeat_flag && _signal))
+            if (_abort || (!_opts.repeat_flag && _signal))
                 break;
         }
     }
-    while (repeat_flag && !_signal);
+    while (_opts.repeat_flag && !_signal);
 }
 
 // static fn:
@@ -146,15 +128,14 @@
 test_mgr::initialize_jrnls()
 {
     _ji_list.clear();
-    for (unsigned i=0; i<_num_jrnls; i++)
+    for (unsigned i=0; i<_opts.num_jrnls; i++)
     {
         std::ostringstream jid;
         jid << std::hex << std::setfill('0');
         jid << "test_" << std::setw(2) << std::hex << i;
         std::ostringstream jdir;
         jdir << "/tmp/" << jid.str();
-        jrnl_init_params::shared_ptr jpp(new jrnl_init_params(jid.str(), jdir.str(),
-                jid.str()));
+        jrnl_init_params::shared_ptr jpp(new jrnl_init_params(jid.str(), jdir.str(), jid.str()));
         jrnl_instance::shared_ptr jip(new jrnl_instance(jpp));
         _ji_list.push_back(jip);
     }

Modified: store/trunk/cpp/tests/jrnl/jtt/test_mgr.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtt/test_mgr.hpp	2008-01-22 21:45:19 UTC (rev 1598)
+++ store/trunk/cpp/tests/jrnl/jtt/test_mgr.hpp	2008-01-23 20:31:53 UTC (rev 1599)
@@ -25,8 +25,8 @@
 #define rhm_jtt_test_mgr_hpp
 
 #include "jrnl_instance.hpp"
+#include "options.hpp"
 #include <signal.h>
-//#include "test_case_result_agregation.hpp"
 
 namespace rhm
 {
@@ -41,16 +41,14 @@
 
     private:
         ji_list _ji_list;
-        unsigned _num_jrnls;
+        options& _opts;
         static volatile sig_atomic_t _signal;
         static volatile bool _abort;
 
     public:
-        test_mgr(const unsigned num_jrnls);
+        test_mgr(options& opts);
         ~test_mgr();
-        void run(const std::string& tc_csv_file_name, const bool jrnl_format_chk,
-                const bool reuse_instance, const bool recover_mode, const bool random_test_order,
-                const bool repeat_flag, const bool keep_jrnls);
+        void run();
         
         static void signal_handler(int signal);
 




More information about the rhmessaging-commits mailing list