#include #include #include #include #include #include #include "config.h" #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include "TestByte.h" #include "TestInt16.h" #include "TestInt32.h" #include "TestUInt16.h" #include "TestUInt32.h" #include "TestFloat32.h" #include "TestFloat64.h" #include "TestStr.h" #include "TestUrl.h" #include "TestArray.h" #include "TestStructure.h" #include "TestSequence.h" #include "DataDDS.h" #include "ConstraintEvaluator.h" #include "TestTypeFactory.h" #include "XDRFileMarshaller.h" #include "XDRStreamMarshaller.h" #include "XDRFileUnMarshaller.h" #include "GetOpt.h" #include "debug.h" using std::cerr; using std::cout; using std::endl; using std::ofstream; using namespace CppUnit; int test_variable_sleep_interval = 0; // Used in Test* classes for testing timeouts. static bool debug = false; #undef DBG #define DBG(x) do { if (debug) {x;} } while(false) /** * This test has been rewritten so that it no longer depends on the values * of Array remaining in place (in the Array object) once serialize() is run. * This is part of a change in libdap that will reduce memory consumption * when serializing datasets with large numbers of (large) variables. * jhrg 8/4/15 */ class marshT: public CppUnit::TestFixture { private: TestByte *b; TestInt16 *i16; TestInt32 *i32; TestUInt16 *ui16; TestUInt32 *ui32; TestFloat32 *f32; TestFloat64 *f64; TestStr *str; TestUrl *url; TestByte *ab; TestArray *arr; TestStructure *s; TestSequence *seq, *seq2; public: marshT() : b(0), i16(0), i32(0), ui16(0), ui32(0), f32(0), f64(0), str(0), url(0), ab(0), arr(0), s(0), seq(0), seq2(0) { } void setUp() { b = new TestByte("b"); i16 = new TestInt16("i16"); i32 = new TestInt32("i32"); ui16 = new TestUInt16("ui16"); ui32 = new TestUInt32("ui32"); f32 = new TestFloat32("f32"); f64 = new TestFloat64("f64"); str = new TestStr("str"); url = new TestUrl("url"); ab = new TestByte("ab"); arr = new TestArray("arr", ab); arr->append_dim(5, "dim1"); arr->append_dim(3, "dim2"); s = new TestStructure("s"); s->add_var(i32); s->add_var(str); s->add_var(arr); s->set_send_p(true); seq = new TestSequence("seq"); seq->add_var(f64); seq->add_var(arr); seq2 = new TestSequence("seq2"); seq2->add_var(ui16); seq2->add_var(url); seq2->set_send_p(true); seq->add_var(seq2); seq->set_send_p(true); seq->set_leaf_sequence(); // Need to call read so that the value() method calls in the ..read_test() // will work. b->read(); i16->read(); i32->read(); ui16->read(); ui32->read(); f32->read(); f64->read(); str->read(); url->read(); arr->read(); s->read(); } void tearDown() { delete b; b = 0; delete i16; i16 = 0; delete i32; i32 = 0; delete ui16; ui16 = 0; delete ui32; ui32 = 0; delete f32; f32 = 0; delete f64; f64 = 0; delete str; str = 0; delete url; url = 0; delete ab; ab = 0; delete arr; arr = 0; delete s; s = 0; } void marshT_test_write(Marshaller &fm) { ConstraintEvaluator eval; TestTypeFactory ttf; DataDDS dds(&ttf, "dds"); try { DBG(cerr << "serializing using XDRFileMarshaller" << endl); b->serialize(eval, dds, fm, false); i16->serialize(eval, dds, fm, false); i32->serialize(eval, dds, fm, false); ui16->serialize(eval, dds, fm, false); ui32->serialize(eval, dds, fm, false); f32->serialize(eval, dds, fm, false); f64->serialize(eval, dds, fm, false); str->serialize(eval, dds, fm, false); url->serialize(eval, dds, fm, false); s->serialize(eval, dds, fm, false); arr->serialize(eval, dds, fm, false); seq->serialize(eval, dds, fm, false); DBG(cerr << "done serializing using XDRFileMarshaller" << endl); } catch (Error &e) { string err = "failed:" + e.get_error_message(); CPPUNIT_FAIL(err.c_str()); } } // This test depends on the file written by the .._write_file() test, // so it must be run after that test. void marshT_test_read(UnMarshaller &um) { TestTypeFactory ttf; DataDDS dds(&ttf, "dds"); // now read the values in and compare the with each other and the original values try { DBG(cerr << "deserializing XDRFileMarshaller built file" << endl); Byte fb("fb"); fb.deserialize(um, &dds, false); CPPUNIT_ASSERT(fb.value() == b->value()); Int16 fi16("i16"); fi16.deserialize(um, &dds, false); DBG(cerr << "fi16.value(): " << fi16.value() << ", i16.value(): " << i16->value()); CPPUNIT_ASSERT(fi16.value() == 32000); DBG(cerr << " file int32" << endl); Int32 fi32("i32"); fi32.deserialize(um, &dds, false); DBG(cerr << "fi32.value(): " << fi32.value() << ", i32.value(): " << i32->value()); CPPUNIT_ASSERT(fi32.value() == i32->value()); UInt16 fui16("ui16"); fui16.deserialize(um, &dds, false); DBG(cerr << "fui16.value(): " << fui16.value() << ", ui16.value(): " << ui16->value()); CPPUNIT_ASSERT(fui16.value() == ui16->value()); UInt32 fui32("ui32"); fui32.deserialize(um, &dds, false); DBG(cerr << "fui32.value(): " << fui32.value() << ", ui32.value(): " << ui32->value()); CPPUNIT_ASSERT(fui32.value() == ui32->value()); Float32 ff32("f32"); ff32.deserialize(um, &dds, false); DBG(cerr << "ff32.value(): " << ff32.value() << ", f32.value(): " << f32->value()); CPPUNIT_ASSERT(ff32.value() == f32->value()); Float64 ff64("f64"); ff64.deserialize(um, &dds, false); DBG(cerr << "ff64.value(): " << ff64.value() << ", f64.value(): " << f64->value()); CPPUNIT_ASSERT(ff64.value() == f64->value()); Str fstr("str"); fstr.deserialize(um, &dds, false); DBG(cerr << "fstr.value(): " << fstr.value() << ", str.value(): " << str->value()); CPPUNIT_ASSERT(fstr.value() == str->value()); Url furl("url"); furl.deserialize(um, &dds, false); DBG(cerr << "furl.value(): " << furl.value() << ", url.value(): " << url->value()); CPPUNIT_ASSERT(furl.value() == url->value()); TestStructure fs("fs"); TestInt32 fsi32("fsi32"); fs.add_var(&fsi32); TestStr fsstr("fsstr"); fs.add_var(&fsstr); TestByte fsab("fsab"); TestArray fsarr("fsarr", &fsab); fsarr.append_dim(5, "dim1"); fsarr.append_dim(3, "dim2"); fs.add_var(&fsarr); fs.deserialize(um, &dds, false); Int32 *fsi32_p = dynamic_cast(fs.var("fsi32")); CPPUNIT_ASSERT(fsi32_p); DBG(cerr << "fsi32.value(): " << fsi32_p->value() << ", i32.value(): " << i32->value()); CPPUNIT_ASSERT(fsi32_p->value() == i32->value()); Str *fsstr_p = dynamic_cast(fs.var("fsstr")); CPPUNIT_ASSERT(fsstr_p); DBG( cerr << "fstr.value(): " << fsstr_p->value() << ", str.value(): " << dynamic_cast(s->var("str"))->value()); CPPUNIT_ASSERT(fsstr_p->value() == dynamic_cast(s->var("str"))->value()); BaseType *bt = fs.var("fsab"); CPPUNIT_ASSERT(bt); Array *fsarr_p = dynamic_cast(bt); CPPUNIT_ASSERT(fsarr_p); dods_byte fdb[fsarr_p->length() * sizeof(dods_byte)]; dods_byte db[arr->length() * sizeof(dods_byte)]; fsarr_p->value(fdb); arr->value(db); CPPUNIT_ASSERT(fsarr_p->length() == arr->length()); CPPUNIT_ASSERT(!memcmp((void *) fdb, (void *) db, fsarr_p->length() * sizeof(dods_byte))); DBG(cerr << " file array" << endl); TestByte fab("ab"); TestArray farr("arr", &fab); farr.append_dim(5, "dim1"); farr.append_dim(3, "dim2"); farr.deserialize(um, &dds, false); farr.value(fdb); CPPUNIT_ASSERT(farr.length() == arr->length()); CPPUNIT_ASSERT(!memcmp((void *) fdb, (void *) db, farr.length() * sizeof(dods_byte))); TestSequence fseq("fseq"); fseq.add_var(f64); fseq.add_var(arr); TestSequence fseq2("fseq2"); fseq2.add_var(ui16); fseq2.add_var(url); fseq2.set_send_p(true); fseq.add_var(&fseq2); fseq.set_leaf_sequence(); fseq.deserialize(um, &dds, false); unsigned int num_rows = fseq.number_of_rows(); CPPUNIT_ASSERT(num_rows == 4); for (unsigned int i = 0; i < num_rows; i++) { BaseTypeRow *row = fseq.row_value(i); CPPUNIT_ASSERT(row); CPPUNIT_ASSERT(row->size() == 3); Float64 *f64_p = dynamic_cast((*row)[0]); CPPUNIT_ASSERT(f64_p); CPPUNIT_ASSERT(f64_p->value() == f64->value()); Array *arr_p = dynamic_cast((*row)[1]); CPPUNIT_ASSERT(arr_p); arr_p->value(fdb); CPPUNIT_ASSERT(arr_p->length() == arr->length()); CPPUNIT_ASSERT(!memcmp((void *) fdb, (void *) db, arr_p->length() * sizeof(dods_byte))); Sequence *seq_p = dynamic_cast((*row)[2]); CPPUNIT_ASSERT(seq_p); unsigned int num_rows_sub = seq_p->number_of_rows(); CPPUNIT_ASSERT(num_rows == 4); for (unsigned int j = 0; j < num_rows_sub; j++) { BaseTypeRow *row_sub = seq_p->row_value(j); CPPUNIT_ASSERT(row_sub); CPPUNIT_ASSERT(row_sub->size() == 2); UInt16 *ui16_p = dynamic_cast((*row_sub)[0]); CPPUNIT_ASSERT(ui16_p); CPPUNIT_ASSERT(ui16_p->value() == ui16->value()); Url *url_p = dynamic_cast((*row_sub)[1]); CPPUNIT_ASSERT(url_p); CPPUNIT_ASSERT(url_p->value() == url->value()); } } DBG(cerr << "done deserializing XDRFileMarshaller built file" << endl); } catch (Error &e) { string err = "failed:" + e.get_error_message(); CPPUNIT_FAIL(err.c_str()); } } void marshT_test_write_file() { FILE *f = fopen("test.file", "w"); XDRFileMarshaller fm(f); marshT_test_write(fm); fclose(f); } void marshT_test_read_file() { FILE *ff = fopen("test.file", "r"); XDRFileUnMarshaller um(ff); marshT_test_read(um); fclose(ff); unlink("test.file"); } void marshT_test_write_stream() { ofstream strm("test.strm", ios::out | ios::trunc); XDRStreamMarshaller sm(strm); marshT_test_write(sm); strm.close(); } // Not that compelling a test really... (It is the same as .._read_file()) void marshT_test_read_stream() { FILE *sf = fopen("test.strm", "r"); XDRFileUnMarshaller um(sf); marshT_test_read(um); fclose(sf); unlink("test.strm"); } CPPUNIT_TEST_SUITE (marshT); CPPUNIT_TEST (marshT_test_write_file); CPPUNIT_TEST (marshT_test_read_file); CPPUNIT_TEST (marshT_test_write_stream); CPPUNIT_TEST (marshT_test_read_stream); CPPUNIT_TEST_SUITE_END( ); }; CPPUNIT_TEST_SUITE_REGISTRATION (marshT); int main(int argc, char *argv[]) { GetOpt getopt(argc, argv, "dh"); int option_char; while ((option_char = getopt()) != -1) switch (option_char) { case 'd': debug = 1; // debug is a static global break; case 'h': { // help - show test names cerr << "Usage: marshT has the following tests:" << endl; const std::vector &tests = marshT::suite()->getTests(); unsigned int prefix_len = marshT::suite()->getName().append("::").length(); for (std::vector::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) { cerr << (*i)->getName().replace(0, prefix_len, "") << endl; } break; } default: break; } CppUnit::TextTestRunner runner; runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); bool wasSuccessful = true; string test = ""; int i = getopt.optind; if (i == argc) { // run them all wasSuccessful = runner.run(""); } else { for (; i < argc; ++i) { if (debug) cerr << "Running " << argv[i] << endl; test = marshT::suite()->getName().append("::").append(argv[i]); wasSuccessful = wasSuccessful && runner.run(test); } } return wasSuccessful ? 0 : 1; }