CalcExtContextTest.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calctest/CalcExtContextTest.cpp#3 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/test/TestBase.h"
00025 #include "fennel/common/TraceSource.h"
00026 
00027 #include "fennel/tuple/TupleDataWithBuffer.h"
00028 #include "fennel/tuple/TuplePrinter.h"
00029 #include "fennel/calculator/CalcCommon.h"
00030 #include "fennel/calculator/StringToHex.h"
00031 #include "fennel/calculator/InstructionFactory.h"
00032 #include "fennel/common/FennelExcn.h"
00033 #include "fennel/calculator/ExtendedInstructionTable.h"
00034 #include "fennel/calculator/ExtendedInstruction.h"
00035 
00036 #include <boost/test/test_tools.hpp>
00037 #include <boost/scoped_array.hpp>
00038 #include <string>
00039 #include <limits>
00040 
00041 
00042 using namespace fennel;
00043 using namespace std;
00044 
00045 
00046 class CalcExtContextTest : virtual public TestBase, public TraceSource
00047 {
00048     void setupExtendedTestInstructions();
00049     void testCalcExtContext();
00050     void testCalcExtContextPost();
00051 
00052     void printOutput(
00053         TupleData const & tup,
00054         Calculator const & calc);
00055 
00056 public:
00057     explicit CalcExtContextTest()
00058         : TraceSource(shared_from_this(),"CalcExtContextTest")
00059     {
00060         CalcInit::instance();
00061         FENNEL_UNIT_TEST_CASE(CalcExtContextTest, testCalcExtContext);
00062         FENNEL_UNIT_TEST_CASE(CalcExtContextTest, testCalcExtContextPost);
00063     }
00064 
00065     virtual ~CalcExtContextTest()
00066     {
00067     }
00068 };
00069 
00070 // for nitty-gritty debugging. sadly, doesn't use BOOST_MESSAGE.
00071 void
00072 CalcExtContextTest::printOutput(
00073     TupleData const & tup,
00074     Calculator const & calc)
00075 {
00076 #if 0
00077     TuplePrinter tuplePrinter;
00078     tuplePrinter.print(cout, calc.getOutputRegisterDescriptor(), tup);
00079     cout << endl;
00080 #endif
00081 }
00082 
00083 // Simple context class for testing purposes. Not thread safe.
00084 class EICtx : public ExtendedInstructionContext
00085 {
00086 public:
00087     EICtx()
00088     {
00089         mCount++;
00090         BOOST_MESSAGE(mCount);
00091     }
00092     ~EICtx()
00093     {
00094         mCount--;
00095         BOOST_MESSAGE(mCount);
00096     }
00097     static int mCount;
00098 };
00099 
00100 int EICtx::mCount = 0;
00101 
00102 void
00103 ctxInst1(
00104     boost::scoped_ptr<ExtendedInstructionContext>& context,
00105     RegisterRef<bool>* op)
00106 {
00107     if (context.get()) {
00108         op->value(false);
00109     } else {
00110         context.reset(new EICtx);
00111         op->value(true);
00112     }
00113 }
00114 
00115 void
00116 ctxInst2(
00117     boost::scoped_ptr<ExtendedInstructionContext>& context,
00118     RegisterRef<bool>* op,
00119     RegisterRef<bool>* dummy2)
00120 {
00121     if (context.get()) {
00122         op->value(false);
00123     } else {
00124         context.reset(new EICtx);
00125         op->value(true);
00126     }
00127 }
00128 
00129 void
00130 ctxInst3(
00131     boost::scoped_ptr<ExtendedInstructionContext>& context,
00132     RegisterRef<bool>* op,
00133     RegisterRef<bool>* dummy2,
00134     RegisterRef<bool>* dummy3)
00135 {
00136     if (context.get()) {
00137         op->value(false);
00138     } else {
00139         context.reset(new EICtx);
00140         op->value(true);
00141     }
00142 }
00143 
00144 void
00145 ctxInst4(
00146     boost::scoped_ptr<ExtendedInstructionContext>& context,
00147     RegisterRef<bool>* op,
00148     RegisterRef<bool>* dummy2,
00149     RegisterRef<bool>* dummy3,
00150     RegisterRef<bool>* dummy4)
00151 {
00152     if (context.get()) {
00153         op->value(false);
00154     } else {
00155         context.reset(new EICtx);
00156         op->value(true);
00157     }
00158 }
00159 
00160 void
00161 ctxInst5(
00162     boost::scoped_ptr<ExtendedInstructionContext>& context,
00163     RegisterRef<bool>* op,
00164     RegisterRef<bool>* dummy2,
00165     RegisterRef<bool>* dummy3,
00166     RegisterRef<bool>* dummy4,
00167     RegisterRef<bool>* dummy5)
00168 {
00169     if (context.get()) {
00170         op->value(false);
00171     } else {
00172         context.reset(new EICtx);
00173         op->value(true);
00174     }
00175 }
00176 
00177 void
00178 CalcExtContextTest::setupExtendedTestInstructions()
00179 {
00180     ExtendedInstructionTable* eit =
00181         InstructionFactory::getExtendedInstructionTable();
00182     ExtendedInstructionDef* inst;
00183 
00184     vector<StandardTypeDescriptorOrdinal> params;
00185     params.push_back(STANDARD_TYPE_BOOL);
00186 
00187     eit->add(
00188         "ctxInst1", params,
00189         (ExtendedInstruction1Context<bool>*) NULL,
00190         ctxInst1);
00191     inst = (*eit)["ctxInst1(bo)"];
00192     BOOST_REQUIRE(inst);
00193     BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst1"));
00194     BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 1);
00195 
00196 
00197     params.push_back(STANDARD_TYPE_BOOL);
00198 
00199     eit->add(
00200         "ctxInst2", params,
00201         (ExtendedInstruction2Context<bool,bool>*) NULL,
00202         ctxInst2);
00203     inst = (*eit)["ctxInst2(bo,bo)"];
00204     BOOST_REQUIRE(inst);
00205     BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst2"));
00206     BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 2);
00207 
00208 
00209     params.push_back(STANDARD_TYPE_BOOL);
00210 
00211     eit->add(
00212         "ctxInst3", params,
00213         (ExtendedInstruction3Context<bool,bool,bool>*) NULL,
00214         ctxInst3);
00215     inst = (*eit)["ctxInst3(bo,bo,bo)"];
00216     BOOST_REQUIRE(inst);
00217     BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst3"));
00218     BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 3);
00219 
00220 
00221     params.push_back(STANDARD_TYPE_BOOL);
00222 
00223     eit->add(
00224         "ctxInst4", params,
00225         (ExtendedInstruction4Context<bool,bool,bool,bool>*) NULL,
00226         ctxInst4);
00227     inst = (*eit)["ctxInst4(bo,bo,bo,bo)"];
00228     BOOST_REQUIRE(inst);
00229     BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst4"));
00230     BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 4);
00231 
00232 
00233     params.push_back(STANDARD_TYPE_BOOL);
00234 
00235     eit->add(
00236         "ctxInst5", params,
00237         (ExtendedInstruction5Context<bool,bool,bool,bool,bool>*) NULL,
00238         ctxInst5);
00239     inst = (*eit)["ctxInst5(bo,bo,bo,bo,bo)"];
00240     BOOST_REQUIRE(inst);
00241     BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst5"));
00242     BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 5);
00243 
00244 }
00245 
00246 
00247 void
00248 CalcExtContextTest::testCalcExtContext()
00249 {
00250     // add in some extended instructions after init
00251     setupExtendedTestInstructions();
00252 
00253     ostringstream pg("");
00254 
00255     pg << "O bo,bo,bo,bo,bo,bo;" << endl;
00256     pg << "L bo,bo,bo,bo,bo,bo;" << endl;
00257     pg << "C bo;" << endl;
00258     pg << "V 0;" << endl;
00259     pg << "T;" << endl;
00260     pg << "MOVE L1, C0;" << endl;
00261     pg << "MOVE L2, C0;" << endl;
00262     pg << "MOVE L3, C0;" << endl;
00263     pg << "MOVE L4, C0;" << endl;
00264     pg << "MOVE L5, C0;" << endl;
00265     pg << "CALL 'ctxInst1(L1);" << endl;
00266     pg << "CALL 'ctxInst2(L2,L0);" << endl;
00267     pg << "CALL 'ctxInst3(L3,L0,L0);" << endl;
00268     pg << "CALL 'ctxInst4(L4,L0,L0,L0);" << endl;
00269     pg << "CALL 'ctxInst5(L5,L0,L0,L0,L0);" << endl;
00270     pg << "REF O0, L0;" << endl;
00271     pg << "REF O1, L1;" << endl;
00272     pg << "REF O2, L2;" << endl;
00273     pg << "REF O3, L3;" << endl;
00274     pg << "REF O4, L4;" << endl;
00275     pg << "REF O5, L5;" << endl;
00276 
00277     //    BOOST_MESSAGE(pg.str());
00278 
00279     Calculator calc(0);
00280 
00281     try {
00282         calc.assemble(pg.str().c_str());
00283     } catch (FennelExcn& ex) {
00284         BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00285         BOOST_MESSAGE(pg.str());
00286         BOOST_REQUIRE(0);
00287     }
00288 
00289     TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00290     TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00291 
00292     calc.bind(&inTuple, &outTuple);
00293     calc.exec();
00294     printOutput(outTuple, calc);
00295 
00296     int i;
00297     for (i = 1; i <= 5; i++) {
00298         BOOST_CHECK_EQUAL(
00299             *(reinterpret_cast<bool *>(
00300                 const_cast<PBuffer>((outTuple[i]).pData))),
00301             true);
00302     }
00303 
00304     // call program again, should get different output
00305     calc.exec();
00306 
00307     for (i = 1; i <= 5; i++) {
00308         BOOST_CHECK_EQUAL(
00309             *(reinterpret_cast<bool *>(
00310                 const_cast<PBuffer>((outTuple[i]).pData))),
00311             false);
00312     }
00313 
00314     // call program again, should get same output
00315     calc.exec();
00316 
00317     for (i = 1; i <= 5; i++) {
00318         BOOST_CHECK_EQUAL(
00319             *(reinterpret_cast<bool *>(
00320                 const_cast<PBuffer>((outTuple[i]).pData))),
00321             false);
00322     }
00323 
00324 #if 0
00325     tuplePrinter.print(cout, calc.getOutputRegisterDescriptor(), outTuple);
00326     cout << endl;
00327 #endif
00328 
00329 }
00330 
00331 // be sure that all context objects were destroyed
00332 void
00333 CalcExtContextTest::testCalcExtContextPost()
00334 {
00335     BOOST_CHECK_EQUAL(EICtx::mCount, 0);
00336 }
00337 
00338 
00339 FENNEL_UNIT_TEST_SUITE(CalcExtContextTest);
00340 
00341 // End CalcExtContextTest.cpp

Generated on Mon Jun 22 04:00:13 2009 for Fennel by  doxygen 1.5.1