/usr/share/cruisecontrol-bin-2.6.1/projects/qpid-trunk/cpp/src/tests/TxMocks.h

00001 /*
00002  *
00003  * Licensed to the Apache Software Foundation (ASF) under one
00004  * or more contributor license agreements.  See the NOTICE file
00005  * distributed with this work for additional information
00006  * regarding copyright ownership.  The ASF licenses this file
00007  * to you under the Apache License, Version 2.0 (the
00008  * "License"); you may not use this file except in compliance
00009  * with the License.  You may obtain a copy of the License at
00010  * 
00011  *   http://www.apache.org/licenses/LICENSE-2.0
00012  * 
00013  * Unless required by applicable law or agreed to in writing,
00014  * software distributed under the License is distributed on an
00015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00016  * KIND, either express or implied.  See the License for the
00017  * specific language governing permissions and limitations
00018  * under the License.
00019  *
00020  */
00021 #ifndef _tests_TxMocks_h
00022 #define _tests_TxMocks_h
00023 
00024 
00025 #include "qpid/Exception.h"
00026 #include "qpid/broker/TransactionalStore.h"
00027 #include "qpid/broker/TxOp.h"
00028 #include <iostream>
00029 #include <vector>
00030 
00031 using namespace qpid::broker;
00032 using boost::static_pointer_cast;
00033 using std::string;
00034 
00035 template <class T> void assertEqualVector(std::vector<T>& expected, std::vector<T>& actual){
00036     unsigned int i = 0;
00037     while(i < expected.size() && i < actual.size()){
00038         CPPUNIT_ASSERT_EQUAL(expected[i], actual[i]);
00039         i++;
00040     }
00041     if (i < expected.size()) {
00042         throw qpid::Exception(QPID_MSG("Missing " << expected[i]));
00043     } else if (i < actual.size()) {
00044         throw qpid::Exception(QPID_MSG("Extra " << actual[i]));
00045     }
00046     CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size());
00047 }
00048 
00049 class TxOpConstants{
00050 protected:
00051     const string PREPARE;
00052     const string COMMIT;
00053     const string ROLLBACK;
00054 
00055     TxOpConstants() : PREPARE("PREPARE"), COMMIT("COMMIT"), ROLLBACK("ROLLBACK") {}
00056 };
00057 
00058 class MockTxOp : public TxOp, public TxOpConstants{
00059     std::vector<string> expected;
00060     std::vector<string> actual;
00061     bool failOnPrepare;
00062     string debugName;
00063 public:
00064     typedef boost::shared_ptr<MockTxOp> shared_ptr;
00065     
00066     MockTxOp() : failOnPrepare(false) {}
00067     MockTxOp(bool _failOnPrepare) : failOnPrepare(_failOnPrepare) {}
00068         
00069     void setDebugName(string name){
00070         debugName = name;
00071     }
00072 
00073     void printExpected(){        
00074         std::cout << std::endl << "MockTxOp[" << debugName << "] expects: ";
00075         for (std::vector<string>::iterator i = expected.begin(); i < expected.end(); i++) {
00076             if(i != expected.begin()) std::cout << ", ";
00077             std::cout << *i;
00078         }
00079         std::cout << std::endl;
00080     }
00081 
00082     void printActual(){        
00083         std::cout << std::endl << "MockTxOp[" << debugName << "] actual: ";
00084         for (std::vector<string>::iterator i = actual.begin(); i < actual.end(); i++) {
00085             if(i != actual.begin()) std::cout << ", ";
00086             std::cout << *i;
00087         }
00088         std::cout << std::endl;
00089     }
00090             
00091     bool prepare(TransactionContext*) throw(){
00092         actual.push_back(PREPARE);
00093         return !failOnPrepare;
00094     }
00095     void commit()  throw(){
00096         actual.push_back(COMMIT);
00097     }
00098     void rollback()  throw(){
00099         if(!debugName.empty()) std::cout << std::endl << "MockTxOp[" << debugName << "]::rollback()" << std::endl;
00100         actual.push_back(ROLLBACK);
00101     }
00102     MockTxOp& expectPrepare(){
00103         expected.push_back(PREPARE);
00104         return *this;
00105     }
00106     MockTxOp& expectCommit(){
00107         expected.push_back(COMMIT);
00108         return *this;
00109     }
00110     MockTxOp& expectRollback(){
00111         expected.push_back(ROLLBACK);
00112         return *this;
00113     }
00114     void check(){
00115         assertEqualVector(expected, actual);
00116     }
00117     ~MockTxOp(){}        
00118 };
00119 
00120 class MockTransactionalStore : public TransactionalStore{
00121     const string BEGIN;
00122     const string BEGIN2PC;
00123     const string PREPARE;
00124     const string COMMIT;
00125     const string ABORT;
00126     std::vector<string> expected;
00127     std::vector<string> actual;
00128     
00129     enum states {OPEN = 1, PREPARED = 2, COMMITTED = 3, ABORTED = 4};
00130     int state;
00131     
00132     class TestTransactionContext : public TPCTransactionContext{
00133         MockTransactionalStore* store;
00134     public:
00135         TestTransactionContext(MockTransactionalStore* _store) : store(_store) {}
00136         void prepare(){
00137             if(!store->isOpen()) throw "txn already completed";
00138             store->state = PREPARED;
00139         }
00140 
00141         void commit(){
00142             if(!store->isOpen() && !store->isPrepared()) throw "txn already completed";
00143             store->state = COMMITTED;
00144         }
00145         
00146         void abort(){
00147             if(!store->isOpen() && !store->isPrepared()) throw "txn already completed";
00148             store->state = ABORTED;
00149         }
00150         ~TestTransactionContext(){}
00151     };
00152     
00153 public:
00154     MockTransactionalStore() :
00155             BEGIN("BEGIN"), BEGIN2PC("BEGIN2PC"), PREPARE("PREPARE"), COMMIT("COMMIT"), ABORT("ABORT"),  state(OPEN){}
00156 
00157     void collectPreparedXids(std::set<std::string>&)
00158     {
00159         throw "Operation not supported";            
00160     }
00161         
00162     std::auto_ptr<TPCTransactionContext> begin(const std::string&){ 
00163         actual.push_back(BEGIN2PC);
00164         std::auto_ptr<TPCTransactionContext> txn(new TestTransactionContext(this));
00165         return txn;
00166     }
00167     std::auto_ptr<TransactionContext> begin(){ 
00168         actual.push_back(BEGIN);
00169         std::auto_ptr<TransactionContext> txn(new TestTransactionContext(this));
00170         return txn;
00171     }
00172     void prepare(TPCTransactionContext& ctxt){
00173         actual.push_back(PREPARE);
00174         dynamic_cast<TestTransactionContext&>(ctxt).prepare();
00175     }
00176     void commit(TransactionContext& ctxt){
00177         actual.push_back(COMMIT);
00178         dynamic_cast<TestTransactionContext&>(ctxt).commit();
00179     }
00180     void abort(TransactionContext& ctxt){
00181         actual.push_back(ABORT);
00182         dynamic_cast<TestTransactionContext&>(ctxt).abort();
00183     }        
00184     MockTransactionalStore& expectBegin(){
00185         expected.push_back(BEGIN);
00186         return *this;
00187     }
00188     MockTransactionalStore& expectBegin2PC(){
00189         expected.push_back(BEGIN2PC);
00190         return *this;
00191     }
00192     MockTransactionalStore& expectPrepare(){
00193         expected.push_back(PREPARE);
00194         return *this;
00195     }
00196     MockTransactionalStore& expectCommit(){
00197         expected.push_back(COMMIT);
00198         return *this;
00199     }
00200     MockTransactionalStore& expectAbort(){
00201         expected.push_back(ABORT);
00202         return *this;
00203     }
00204     void check(){
00205         assertEqualVector(expected, actual);
00206     }
00207     
00208     bool isPrepared(){
00209         return state == PREPARED;
00210     }
00211     
00212     bool isCommitted(){
00213         return state == COMMITTED;
00214     }
00215     
00216     bool isAborted(){
00217         return state == ABORTED;
00218     }
00219     
00220     bool isOpen() const{
00221         return state == OPEN;
00222     }
00223     ~MockTransactionalStore(){}
00224 };
00225 
00226 #endif

Generated on Thu Apr 10 11:08:18 2008 for Qpid by  doxygen 1.4.7