diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /searchsummary/src/tests/docsumformat |
Publish
Diffstat (limited to 'searchsummary/src/tests/docsumformat')
34 files changed, 1178 insertions, 0 deletions
diff --git a/searchsummary/src/tests/docsumformat/.gitignore b/searchsummary/src/tests/docsumformat/.gitignore new file mode 100644 index 00000000000..2c841cbd43d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/.gitignore @@ -0,0 +1,21 @@ +*.cfg +*.core +*.ilk +*.out +*.pdb +*.pid +.depend +Makefile +core +core.* +datapart.* +docsum-index +docsum-pack +docsum-parse +index.cf +merged +meta-info.txt +schema.txt +summary.cf +version.txt +searchsummary_docsum-pack_app diff --git a/searchsummary/src/tests/docsumformat/CMakeLists.txt b/searchsummary/src/tests/docsumformat/CMakeLists.txt new file mode 100644 index 00000000000..ac8d2151792 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(searchsummary_docsum-pack_app + SOURCES + docsum-pack.cpp + DEPENDS + searchsummary +) +vespa_add_test(NAME searchsummary_docsum-pack_app COMMAND searchsummary_docsum-pack_app) diff --git a/searchsummary/src/tests/docsumformat/docsum-index.sh b/searchsummary/src/tests/docsumformat/docsum-index.sh new file mode 100755 index 00000000000..0d313191685 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/docsum-index.sh @@ -0,0 +1,16 @@ +#!/bin/sh -e +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +findex=../../../bin/findex + +echo "CLEAN" +rm -f index.cf +rm -f summary.cf +rm -rf merged +rm -rf datapart.* + +echo "DOCSUM-INDEX" +./docsum-index + +echo "AUTOINDEX" +$findex autoindex diff --git a/searchsummary/src/tests/docsumformat/docsum-pack.cpp b/searchsummary/src/tests/docsumformat/docsum-pack.cpp new file mode 100644 index 00000000000..3f1b088bd12 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/docsum-pack.cpp @@ -0,0 +1,631 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright (C) 2001-2003 Fast Search & Transfer ASA +// Copyright (C) 2003 Overture Services Norway AS + + +#include <vespa/fastos/fastos.h> +#include <vespa/log/log.h> +LOG_SETUP("docsum-pack"); +#include <vespa/searchlib/util/rawbuf.h> +#include <vespa/searchsummary/docsummary/urlresult.h> +#include <vespa/searchsummary/docsummary/resultconfig.h> +#include <vespa/searchsummary/docsummary/resultpacker.h> + +using namespace search::docsummary; + + +// needed to resolve external symbol from httpd.h on AIX +void FastS_block_usr2() {} + + +class MyApp : public FastOS_Application +{ +private: + bool _rc; + uint32_t _cnt; + search::docsummary::ResultConfig _config; + search::docsummary::ResultPacker _packer; + +public: + MyApp() + : _rc(false), + _cnt(0u), + _config(), + _packer(&_config) + { + } + + // log test results + void ReportTestResult(uint32_t line, bool rc); + bool RTR(uint32_t line, bool rc) + { ReportTestResult(line, rc); return rc; } + + // compare runtime info (,but ignore result class) + bool Equal(search::docsummary::ResEntry *a, search::docsummary::ResEntry *b); + bool Equal(search::docsummary::GeneralResult *a, search::docsummary::GeneralResult *b); + + void TestFieldIndex(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, int idx); + + void TestIntValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, uint32_t value); + + void TestDoubleValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, double value); + + void TestInt64Value(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, uint64_t value); + + void TestStringValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, const char *value); + + void TestDataValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, const char *value); + + void TestBasic(); + void TestFailLong(); + void TestFailShort(); + void TestFailOrder(); + void TestCompress(); + void TestCompat(); + void TestBasicInplace(); + void TestCompressInplace(); + + int Main(); +}; + + +void +MyApp::ReportTestResult(uint32_t line, bool rc) +{ + _cnt++; + + if (rc) { + LOG(info, "Test case %d: SUCCESS", _cnt); + } else { + LOG(error, "Test case %d: FAIL (see %s:%d)", _cnt, __FILE__, line); + _rc = false; + } +} + + +bool +MyApp::Equal(search::docsummary::ResEntry *a, search::docsummary::ResEntry *b) +{ + if (a->_type != b->_type) + return false; + + if (a->_intval != b->_intval) + return false; + + if (a->_type != RES_INT && + memcmp(a->_pt, b->_pt, a->_intval) != 0) + return false; + + return true; +} + + +bool +MyApp::Equal(search::docsummary::GeneralResult *a, search::docsummary::GeneralResult *b) +{ + uint32_t numEntries = a->GetClass()->GetNumEntries(); + + if (b->GetClass()->GetNumEntries() != numEntries) + return false; + + for (uint32_t i = 0; i < numEntries; i++) { + + if (!Equal(a->GetEntry(i), b->GetEntry(i))) + return false; + + if (a->GetClass()->GetEntry(i)->_bindname != b->GetClass()->GetEntry(i)->_bindname) + return false; + } + + return true; +} + + +void +MyApp::TestFieldIndex(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, int idx) +{ + bool rc = (gres != NULL && + gres->GetClass()->GetIndexFromName(field) == idx); + + RTR(line, rc); +} + + +void +MyApp::TestIntValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, uint32_t value) +{ + search::docsummary::ResEntry *entry + = (gres != NULL) ? gres->GetEntry(field) : NULL; + + bool rc = (entry != NULL && + entry->_type == RES_INT && + entry->_intval == value); + + RTR(line, rc); +} + + +void +MyApp::TestDoubleValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, double value) +{ + search::docsummary::ResEntry *entry + = (gres != NULL) ? gres->GetEntry(field) : NULL; + + bool rc = (entry != NULL && + entry->_type == RES_DOUBLE && + entry->_doubleval == value); + + RTR(line, rc); +} + + +void +MyApp::TestInt64Value(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, uint64_t value) +{ + search::docsummary::ResEntry *entry + = (gres != NULL) ? gres->GetEntry(field) : NULL; + + bool rc = (entry != NULL && + entry->_type == RES_INT64 && + entry->_int64val == value); + + RTR(line, rc); +} + + +void +MyApp::TestStringValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, const char *value) +{ + search::docsummary::ResEntry *entry + = (gres != NULL) ? gres->GetEntry(field) : NULL; + + bool rc = (entry != NULL && + entry->_type == RES_STRING && + entry->_stringlen == strlen(value) && + strncmp(entry->_stringval, value, entry->_stringlen) == 0); + + if (!rc && entry != NULL) { + LOG(warning, + "string value '%.*s' != '%s'", + (int) entry->_stringlen, + entry->_stringval, value); + } + + RTR(line, rc); +} + + +void +MyApp::TestDataValue(uint32_t line, search::docsummary::GeneralResult *gres, + const char *field, const char *value) +{ + search::docsummary::ResEntry *entry + = (gres != NULL) ? gres->GetEntry(field) : NULL; + + bool rc = (entry != NULL && + entry->_type == RES_DATA && + entry->_datalen == strlen(value) && + strncmp(entry->_dataval, value, entry->_datalen) == 0); + + RTR(line, rc); +} + + +void +MyApp::TestBasic() +{ + const char *buf; + uint32_t buflen; + + search::docsummary::urlresult *res; + search::docsummary::GeneralResult *gres; + + uint32_t intval = 4; + uint16_t shortval = 2; + uint8_t byteval = 1; + float floatval = 4.5; + double doubleval = 8.75; + uint64_t int64val = 8; + const char *strval = "This is a string"; + const char *datval = "This is data"; + const char *lstrval = "This is a long string"; + const char *ldatval = "This is long data"; + + RTR(__LINE__, _packer.Init(0)); + RTR(__LINE__, _packer.AddInteger(intval)); + RTR(__LINE__, _packer.AddShort(shortval)); + RTR(__LINE__, _packer.AddByte(byteval)); + RTR(__LINE__, _packer.AddFloat(floatval)); + RTR(__LINE__, _packer.AddDouble(doubleval)); + RTR(__LINE__, _packer.AddInt64(int64val)); + RTR(__LINE__, _packer.AddString(strval, strlen(strval))); + RTR(__LINE__, _packer.AddData(datval, strlen(datval))); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + + res = _config.Unpack(0, 0, 0, buf, buflen); + gres = res->IsGeneral() ? (search::docsummary::GeneralResult *) res : NULL; + + RTR(__LINE__, gres != NULL); + TestIntValue (__LINE__, gres, "integer", 4); + TestIntValue (__LINE__, gres, "short", 2); + TestIntValue (__LINE__, gres, "byte", 1); + TestDoubleValue(__LINE__, gres, "float", floatval); + TestDoubleValue(__LINE__, gres, "double", doubleval); + TestInt64Value (__LINE__, gres, "int64", int64val); + TestStringValue(__LINE__, gres, "string", strval); + TestDataValue (__LINE__, gres, "data", datval); + TestStringValue(__LINE__, gres, "longstring", lstrval); + TestDataValue (__LINE__, gres, "longdata", ldatval); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetNumEntries() == 10)); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetClassID() == 0)); + delete res; +} + + +void +MyApp::TestFailLong() +{ + const char *buf; + uint32_t buflen; + + uint32_t intval = 4; + uint16_t shortval = 2; + uint8_t byteval = 1; + float floatval = 4.5; + double doubleval = 8.75; + uint64_t int64val = 8; + const char *strval = "This is a string"; + const char *datval = "This is data"; + const char *lstrval = "This is a long string"; + const char *ldatval = "This is long data"; + + RTR(__LINE__, _packer.Init(0)); + RTR(__LINE__, _packer.AddInteger(intval)); + RTR(__LINE__, _packer.AddShort(shortval)); + RTR(__LINE__, _packer.AddByte(byteval)); + RTR(__LINE__, _packer.AddFloat(floatval)); + RTR(__LINE__, _packer.AddDouble(doubleval)); + RTR(__LINE__, _packer.AddInt64(int64val)); + RTR(__LINE__, _packer.AddString(strval, strlen(strval))); + RTR(__LINE__, _packer.AddData(datval, strlen(datval))); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, !_packer.AddByte(byteval)); + RTR(__LINE__, !_packer.GetDocsumBlob(&buf, &buflen)); +} + + +void +MyApp::TestFailShort() +{ + const char *buf; + uint32_t buflen; + + uint32_t intval = 4; + uint16_t shortval = 2; + uint8_t byteval = 1; + float floatval = 4.5; + double doubleval = 8.75; + uint64_t int64val = 8; + const char *strval = "This is a string"; + const char *datval = "This is data"; + const char *lstrval = "This is a long string"; + + RTR(__LINE__, _packer.Init(0)); + RTR(__LINE__, _packer.AddInteger(intval)); + RTR(__LINE__, _packer.AddShort(shortval)); + RTR(__LINE__, _packer.AddByte(byteval)); + RTR(__LINE__, _packer.AddFloat(floatval)); + RTR(__LINE__, _packer.AddDouble(doubleval)); + RTR(__LINE__, _packer.AddInt64(int64val)); + RTR(__LINE__, _packer.AddString(strval, strlen(strval))); + RTR(__LINE__, _packer.AddData(datval, strlen(datval))); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, !_packer.GetDocsumBlob(&buf, &buflen)); +} + + +void +MyApp::TestFailOrder() +{ + const char *buf; + uint32_t buflen; + + uint32_t intval = 4; + uint16_t shortval = 2; + uint8_t byteval = 1; + float floatval = 4.5; + double doubleval = 8.75; + uint64_t int64val = 8; + const char *strval = "This is a string"; + const char *datval = "This is data"; + const char *lstrval = "This is a long string"; + const char *ldatval = "This is long data"; + + RTR(__LINE__, _packer.Init(0)); + RTR(__LINE__, _packer.AddInteger(intval)); + RTR(__LINE__, _packer.AddShort(shortval)); + RTR(__LINE__, !_packer.AddString(strval, strlen(strval))); + RTR(__LINE__, !_packer.AddByte(byteval)); + RTR(__LINE__, !_packer.AddFloat(floatval)); + RTR(__LINE__, !_packer.AddDouble(doubleval)); + RTR(__LINE__, !_packer.AddInt64(int64val)); + RTR(__LINE__, !_packer.AddData(datval, strlen(datval))); + RTR(__LINE__, !_packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, !_packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, !_packer.GetDocsumBlob(&buf, &buflen)); +} + + +void +MyApp::TestCompress() +{ + const char *buf; + uint32_t buflen; + + search::docsummary::urlresult *res; + search::docsummary::GeneralResult *gres; + + const char *lstrval = "string string string"; + const char *ldatval = "data data data"; + + RTR(__LINE__, _packer.Init(2)); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + + res = _config.Unpack(0, 0, 0, buf, buflen); + gres = res->IsGeneral() ? (search::docsummary::GeneralResult *) res : NULL; + + RTR(__LINE__, gres != NULL); + TestStringValue(__LINE__, gres, "text", lstrval); + TestDataValue (__LINE__, gres, "data", ldatval); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetNumEntries() == 2)); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetClassID() == 2)); + delete res; +} + + +void +MyApp::TestCompat() +{ + const char *buf; + uint32_t buflen; + + search::docsummary::urlresult *res1; + search::docsummary::GeneralResult *gres1; + + search::docsummary::urlresult *res2; + search::docsummary::GeneralResult *gres2; + + const char *strval = "string string string string"; + const char *datval = "data data data data"; + + RTR(__LINE__, _packer.Init(1)); + RTR(__LINE__, _packer.AddData(strval, strlen(strval))); + RTR(__LINE__, _packer.AddString(datval, strlen(datval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + res1 = _config.Unpack(0, 0, 0, buf, buflen); + gres1 = res1->IsGeneral() ? (search::docsummary::GeneralResult *) res1 : NULL; + + RTR(__LINE__, _packer.Init(2)); + RTR(__LINE__, _packer.AddLongData(strval, strlen(strval))); + RTR(__LINE__, _packer.AddLongString(datval, strlen(datval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + res2 = _config.Unpack(0, 0, 0, buf, buflen); + gres2 = res2->IsGeneral() ? (search::docsummary::GeneralResult *) res2 : NULL; + + RTR(__LINE__, gres1 != NULL); + RTR(__LINE__, gres2 != NULL); + + TestStringValue(__LINE__, gres1, "text", strval); + TestDataValue (__LINE__, gres1, "data", datval); + TestFieldIndex (__LINE__, gres1, "text", 0); + TestFieldIndex (__LINE__, gres1, "data", 1); + RTR(__LINE__, (gres1 != NULL && + gres1->GetClass()->GetNumEntries() == 2)); + + TestStringValue(__LINE__, gres2, "text", strval); + TestDataValue (__LINE__, gres2, "data", datval); + TestFieldIndex (__LINE__, gres2, "text", 0); + TestFieldIndex (__LINE__, gres2, "data", 1); + RTR(__LINE__, (gres2 != NULL && + gres2->GetClass()->GetNumEntries() == 2)); + + RTR(__LINE__, (gres1 != NULL && + gres1->GetClass()->GetClassID() == 1)); + RTR(__LINE__, (gres2 != NULL && + gres2->GetClass()->GetClassID() == 2)); + + RTR(__LINE__, (gres1 != NULL && gres2 != NULL && + Equal(gres1, gres2))); + + delete res1; + delete res2; +} + + +void +MyApp::TestBasicInplace() +{ + const char *buf; + uint32_t buflen; + + const search::docsummary::ResultClass *resClass; + search::docsummary::GeneralResult *gres; + + uint32_t intval = 4; + uint16_t shortval = 2; + uint8_t byteval = 1; + float floatval = 4.5; + double doubleval = 8.75; + uint64_t int64val = 8; + const char *strval = "This is a string"; + const char *datval = "This is data"; + const char *lstrval = "This is a long string"; + const char *ldatval = "This is long data"; + + RTR(__LINE__, _packer.Init(0)); + RTR(__LINE__, _packer.AddInteger(intval)); + RTR(__LINE__, _packer.AddShort(shortval)); + RTR(__LINE__, _packer.AddByte(byteval)); + RTR(__LINE__, _packer.AddFloat(floatval)); + RTR(__LINE__, _packer.AddDouble(doubleval)); + RTR(__LINE__, _packer.AddInt64(int64val)); + RTR(__LINE__, _packer.AddString(strval, strlen(strval))); + RTR(__LINE__, _packer.AddData(datval, strlen(datval))); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + + resClass = _config.LookupResultClass(_config.GetClassID(buf, buflen)); + if (resClass == NULL) { + gres = NULL; + } else { + DocsumStoreValue value(buf, buflen); + gres = new search::docsummary::GeneralResult(resClass, 0, 0, 0); + if (!gres->inplaceUnpack(value)) { + delete gres; + gres = NULL; + } + } + + RTR(__LINE__, gres != NULL); + TestIntValue (__LINE__, gres, "integer", 4); + TestIntValue (__LINE__, gres, "short", 2); + TestIntValue (__LINE__, gres, "byte", 1); + TestDoubleValue(__LINE__, gres, "float", floatval); + TestDoubleValue(__LINE__, gres, "double", doubleval); + TestInt64Value (__LINE__, gres, "int64", int64val); + TestStringValue(__LINE__, gres, "string", strval); + TestDataValue (__LINE__, gres, "data", datval); + TestStringValue(__LINE__, gres, "longstring", lstrval); + TestDataValue (__LINE__, gres, "longdata", ldatval); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetNumEntries() == 10)); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetClassID() == 0)); + delete gres; +} + + +void +MyApp::TestCompressInplace() +{ + const char *buf; + uint32_t buflen; + + search::RawBuf field1(32768); + search::RawBuf field2(32768); + const search::docsummary::ResultClass *resClass; + search::docsummary::GeneralResult *gres; + + const char *lstrval = "string string string"; + const char *ldatval = "data data data"; + + RTR(__LINE__, _packer.Init(2)); + RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); + RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); + RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); + + resClass = _config.LookupResultClass(_config.GetClassID(buf, buflen)); + if (resClass == NULL) { + gres = NULL; + } else { + DocsumStoreValue value(buf, buflen); + gres = new search::docsummary::GeneralResult(resClass, 0, 0, 0); + if (!gres->inplaceUnpack(value)) { + delete gres; + gres = NULL; + } + } + + search::docsummary::ResEntry *e1 = (gres == NULL) ? NULL : gres->GetEntry("text"); + search::docsummary::ResEntry *e2 = (gres == NULL) ? NULL : gres->GetEntry("data"); + + if (e1 != NULL) + e1->_extract_field(&field1); + if (e2 != NULL) + e2->_extract_field(&field2); + + RTR(__LINE__, gres != NULL); + RTR(__LINE__, e1 != NULL); + RTR(__LINE__, e2 != NULL); + RTR(__LINE__, strcmp(field1.GetDrainPos(), lstrval) == 0); + RTR(__LINE__, strcmp(field2.GetDrainPos(), ldatval) == 0); + RTR(__LINE__, strlen(lstrval) == field1.GetUsedLen()); + RTR(__LINE__, strlen(ldatval) == field2.GetUsedLen()); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetNumEntries() == 2)); + RTR(__LINE__, (gres != NULL && + gres->GetClass()->GetClassID() == 2)); + delete gres; +} + + + +int +MyApp::Main() +{ + _rc = true; + _cnt = 0; + + search::docsummary::ResultClass *resClass; + + resClass = _config.AddResultClass("c0", 0); + resClass->AddConfigEntry("integer", RES_INT); + resClass->AddConfigEntry("short", RES_SHORT); + resClass->AddConfigEntry("byte", RES_BYTE); + resClass->AddConfigEntry("float", RES_FLOAT); + resClass->AddConfigEntry("double", RES_DOUBLE); + resClass->AddConfigEntry("int64", RES_INT64); + resClass->AddConfigEntry("string", RES_STRING); + resClass->AddConfigEntry("data", RES_DATA); + resClass->AddConfigEntry("longstring", RES_LONG_STRING); + resClass->AddConfigEntry("longdata", RES_LONG_DATA); + + resClass = _config.AddResultClass("c1", 1); + resClass->AddConfigEntry("text", RES_STRING); + resClass->AddConfigEntry("data", RES_DATA); + + resClass = _config.AddResultClass("c2", 2); + resClass->AddConfigEntry("text", RES_LONG_STRING); + resClass->AddConfigEntry("data", RES_LONG_DATA); + + TestBasic(); + TestFailLong(); + TestFailShort(); + TestFailOrder(); + TestCompress(); + TestCompat(); + TestBasicInplace(); + TestCompressInplace(); + + LOG(info, "CONCLUSION: %s", (_rc) ? "SUCCESS" : "FAIL"); + return (_rc ? 0 : 1); +} + + +int +main(int argc, char **argv) +{ + MyApp myapp; + return myapp.Entry(argc, argv); +} diff --git a/searchsummary/src/tests/docsumformat/docsum-parse.cpp b/searchsummary/src/tests/docsumformat/docsum-parse.cpp new file mode 100644 index 00000000000..5fa7009464c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/docsum-parse.cpp @@ -0,0 +1,201 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright (C) 2001-2003 Fast Search & Transfer ASA +// Copyright (C) 2003 Overture Services Norway AS + + +#include <vespa/fastos/fastos.h> +#include <vespa/log/log.h> +LOG_SETUP("docsum-parse"); +#include <vespa/fnet/frt/frt.h> +#include <vespa/fastlib/io/bufferedfile.h> +#include <vespa/searchsummary/docsummary/urlresult.h> +#include <vespa/searchsummary/docsummary/resultconfig.h> + + +// needed to resolve external symbol from httpd.h on AIX +void FastS_block_usr2() {} + + +class MyApp : public FastOS_Application +{ +public: + bool Equal(search::docsummary::ResConfigEntry *a, search::docsummary::ResConfigEntry *b); + bool Equal(search::docsummary::ResultClass *a, search::docsummary::ResultClass *b); + bool Equal(search::docsummary::ResultConfig *a, search::docsummary::ResultConfig *b); + bool TestCorrect(const char *dirname, const char *filename); + bool TestIncorrect(const char *dirname, const char *filename); + int Main(); +}; + + +bool +MyApp::Equal(search::docsummary::ResConfigEntry *a, search::docsummary::ResConfigEntry *b) +{ + return ((a->_type == b->_type) + && (strcmp(a->_bindname, b->_bindname) == 0)); +} + + +bool +MyApp::Equal(search::docsummary::ResultClass *a, search::docsummary::ResultClass *b) +{ + bool rc = true; + + rc = rc && (a->GetNumEntries() == b->GetNumEntries()); + rc = rc && (a->GetClassID() == b->GetClassID()); + rc = rc && (strcmp(a->GetClassName(), b->GetClassName()) == 0); + + for (uint32_t i = 0; rc && i < a->GetNumEntries(); i++) { + rc = rc && Equal(a->GetEntry(i), b->GetEntry(i)); + } + + return rc; +} + + +bool +MyApp::Equal(search::docsummary::ResultConfig *a, search::docsummary::ResultConfig *b) +{ + bool rc = true; + + search::docsummary::ResultClass *resClassA; + search::docsummary::ResultClass *resClassB; + + rc = rc && (a->GetNumResultClasses() == b->GetNumResultClasses()); + + resClassA = a->GetResultClasses(); + resClassB = b->GetResultClasses(); + + while(rc && resClassA != NULL && resClassB != NULL) { + rc = rc && Equal(resClassA, resClassB); + resClassA = resClassA->GetNextClass(); + resClassB = resClassB->GetNextClass(); + } + rc = rc && (resClassA == NULL); + rc = rc && (resClassB == NULL); + + return rc; +} + + +bool +MyApp::TestCorrect(const char *dirname, const char *filename) +{ + char str1[512]; // test input file + char str2[512]; // test output file + char str3[512]; // summary.cf verification file + + search::docsummary::ResultConfig a; + search::docsummary::ResultConfig b; + search::docsummary::ResultConfig c; + search::docsummary::ResultConfig d; + + sprintf(str1, "%s%s%s", dirname, + FastOS_FileInterface::GetPathSeparator(), filename); + sprintf(str2, "%s%sout.%s", dirname, + FastOS_FileInterface::GetPathSeparator(), filename); + sprintf(str3, "%s%sOK.%s", dirname, + FastOS_FileInterface::GetPathSeparator(), filename); + + if (!a.ReadConfig(str1)) { + LOG(error, "could not read config from : %s", str1); + return false; + } + + if (!a.WriteConfig(str2)) { + LOG(error, "could not write config to : %s", str2); + return false; + } + + if (!b.ReadConfig(str2)) { + LOG(error, "could not read config from : %s", str2); + return false; + } + + if (!c.ReadConfig(str3)) { + LOG(error, "could not read config from : %s", str3); + return false; + } + + if (!Equal(&a, &b)) { + LOG(error, "%s and %s does not contain the same config", str1, str2); + return false; + } + + if (!Equal(&a, &c)) { + LOG(error, "%s and %s does not contain the same config", str1, str3); + return false; + } + + if (!Equal(&b, &c)) { + LOG(error, "%s and %s does not contain the same config", str2, str3); + return false; + } + + FRT_RPCRequest *req = new FRT_RPCRequest(); + assert(req != NULL); + c.GetConfig(req); + d.SetConfig(req); + if (!Equal(&c, &d)) { + LOG(error, "RPC get/set failed (%s)", str3); + req->SubRef(); + return false; + } + req->SubRef(); + + return true; +} + + +bool +MyApp::TestIncorrect(const char *dirname, const char *filename) +{ + char str[512]; + + sprintf(str, "%s%s%s", dirname, + FastOS_FileInterface::GetPathSeparator(), filename); + + search::docsummary::ResultConfig resConfig; + + if (resConfig.ReadConfig(str)) { + LOG(error, "'%s' did not give parse error", str); + return false; + } + return true; +} + + +int +MyApp::Main() +{ + bool rc = true; + + FastOS_DirectoryScan dirScan("parsetest"); + LOG(info, "looking for input files in 'parsetest'..."); + while (dirScan.ReadNext()) { + if (strncmp(dirScan.GetName(), "correct.", 8) == 0) { + if (TestCorrect("parsetest", dirScan.GetName())) { + LOG(info, "'%s' : positive test PASSED", dirScan.GetName()); + } else { + LOG(error, "'%s' : positive test FAILED", dirScan.GetName()); + rc = false; + } + } else if (strncmp(dirScan.GetName(), "incorrect.", 10) == 0) { + if (TestIncorrect("parsetest", dirScan.GetName())) { + LOG(info, "'%s' : negative test PASSED", dirScan.GetName()); + } else { + LOG(error, "'%s' : negative test FAILED", dirScan.GetName()); + rc = false; + } + } + } + return (rc ? 0 : 1); +} + + +int +main(int argc, char **argv) +{ + MyApp myapp; + return myapp.Entry(argc, argv); +} diff --git a/searchsummary/src/tests/docsumformat/dotest.sh b/searchsummary/src/tests/docsumformat/dotest.sh new file mode 100755 index 00000000000..64097b0061d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/dotest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +echo "running pack test..." +./docsum-pack > packtest.out 2>&1 +res=$? +if [ $res -eq 0 ]; then + echo "pack test PASSED" +else + echo "pack test FAILED!" + echo "please check packtest.out" + exit 1 +fi diff --git a/searchsummary/src/tests/docsumformat/parsetest/.gitignore b/searchsummary/src/tests/docsumformat/parsetest/.gitignore new file mode 100644 index 00000000000..19815d313ff --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/.gitignore @@ -0,0 +1,2 @@ +*.out +out.* diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.1 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.1 new file mode 100644 index 00000000000..8238b53f81c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.1 @@ -0,0 +1,17 @@ +idtype none + +class default id 0 +field URL type string +field TITLE type string +field TEASER type string +field DSHOST type integer +field DSKEY type integer +field BYTES type integer +field WORDS type integer +field MODDATE type integer +field CRAWLDATE type integer +field LANG1 type byte +field LANG2 type byte +field LANG3 type byte +field LANG4 type byte +field CHARSET type integer diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.2 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.2 new file mode 100644 index 00000000000..8996c2dac4c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.2 @@ -0,0 +1,14 @@ +idtype byte + +class document id 1 +field title type string +field teaser type string +field url type string +field date type integer + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.3 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.3 new file mode 100644 index 00000000000..ae29fa40335 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.3 @@ -0,0 +1,5 @@ +idtype none + +class default id 0 +field TITLE type string +field DATE type integer diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.4 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.4 new file mode 100644 index 00000000000..8238b53f81c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.4 @@ -0,0 +1,17 @@ +idtype none + +class default id 0 +field URL type string +field TITLE type string +field TEASER type string +field DSHOST type integer +field DSKEY type integer +field BYTES type integer +field WORDS type integer +field MODDATE type integer +field CRAWLDATE type integer +field LANG1 type byte +field LANG2 type byte +field LANG3 type byte +field LANG4 type byte +field CHARSET type integer diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.5 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.5 new file mode 100644 index 00000000000..6b6dc874a68 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.5 @@ -0,0 +1,3 @@ +idtype byte + +class myclass id 42 diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.6 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.6 new file mode 100644 index 00000000000..38416fdf45e --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.6 @@ -0,0 +1,5 @@ +idtype none + +class default id 0 +field TEASER type longstring +field DOCTEXT type longdata diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.7 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.7 new file mode 100644 index 00000000000..d1f17d25141 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.7 @@ -0,0 +1,11 @@ +idtype short + +class class_1 id 1 +field title type string +field rawteaser type data +field doctext type longdata +field dynteaser type longstring + +class class_2 id 2 +field title type string +field rawteaser type longdata diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.8 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.8 new file mode 100644 index 00000000000..e929b872a05 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.8 @@ -0,0 +1,7 @@ +idtype integer + +class class_50 id 50 +field title type data + +class class_100 id 100 +field title type string diff --git a/searchsummary/src/tests/docsumformat/parsetest/OK.correct.9 b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.9 new file mode 100644 index 00000000000..668505be77d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/OK.correct.9 @@ -0,0 +1,13 @@ +idtype none + +class default id 0 +field f0 type integer +field f1 type short +field f2 type byte +field f3 type float +field f4 type double +field f5 type int64 +field f6 type string +field f7 type data +field f8 type longstring +field f9 type longdata diff --git a/searchsummary/src/tests/docsumformat/parsetest/README b/searchsummary/src/tests/docsumformat/parsetest/README new file mode 100644 index 00000000000..2de83e1b0cb --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/README @@ -0,0 +1,24 @@ +The files in this directory are used to test the parsing of document +summary format config files. The files are named by the following +rules: + +incorrect.* : these files are incorrect; loading them should fail. + +correct.* : these files are correct; loading them should succeed. + +OK.correct.* : these files contain normalized config on 'summary.cf' + format that matches the config contained in + the corresponding 'correct.*' files. + +The 'docsum-parse' program loops through all files in this +directory. For each file that has a name beginning with 'incorrect.', +it checks that loading document summary format config from it +fails. For each file that has a name beginning with 'correct.', it +checks that document summary format config may be read from the +file. It then writes the config back to a file named 'out.correct.<>', +reads the newly generated file back in, reads the corresponding +'OK.correct.<>' file and checks that all 3 configs are exactly the +same. + +New tests may be added simply be adding files conforming to the above +rules to this directory. diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.1 b/searchsummary/src/tests/docsumformat/parsetest/correct.1 new file mode 100644 index 00000000000..0b3d57b7f9c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.1 @@ -0,0 +1,14 @@ +STRING URL +STRING TITLE +STRING TEASER +INT DSHOST +INT DSKEY +INT BYTES +INT WORDS +INT MODDATE +INT CRAWLDATE +BYTE LANG1 +BYTE LANG2 +BYTE LANG3 +BYTE LANG4 +INT CHARSET diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.2 b/searchsummary/src/tests/docsumformat/parsetest/correct.2 new file mode 100644 index 00000000000..8996c2dac4c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.2 @@ -0,0 +1,14 @@ +idtype byte + +class document id 1 +field title type string +field teaser type string +field url type string +field date type integer + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.3 b/searchsummary/src/tests/docsumformat/parsetest/correct.3 new file mode 100644 index 00000000000..8a16e3f3fd1 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.3 @@ -0,0 +1,3 @@ +idtype byte +STRING TITLE +INT DATE diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.4 b/searchsummary/src/tests/docsumformat/parsetest/correct.4 new file mode 100644 index 00000000000..8238b53f81c --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.4 @@ -0,0 +1,17 @@ +idtype none + +class default id 0 +field URL type string +field TITLE type string +field TEASER type string +field DSHOST type integer +field DSKEY type integer +field BYTES type integer +field WORDS type integer +field MODDATE type integer +field CRAWLDATE type integer +field LANG1 type byte +field LANG2 type byte +field LANG3 type byte +field LANG4 type byte +field CHARSET type integer diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.5 b/searchsummary/src/tests/docsumformat/parsetest/correct.5 new file mode 100644 index 00000000000..d179537e208 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.5 @@ -0,0 +1,4 @@ +idtype byte +class myclass id 42 +STRING TITLE +INT DATE diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.6 b/searchsummary/src/tests/docsumformat/parsetest/correct.6 new file mode 100644 index 00000000000..a4e41ec72d8 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.6 @@ -0,0 +1,2 @@ +LONGSTRING TEASER +LONGDATA DOCTEXT diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.7 b/searchsummary/src/tests/docsumformat/parsetest/correct.7 new file mode 100644 index 00000000000..d1f17d25141 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.7 @@ -0,0 +1,11 @@ +idtype short + +class class_1 id 1 +field title type string +field rawteaser type data +field doctext type longdata +field dynteaser type longstring + +class class_2 id 2 +field title type string +field rawteaser type longdata diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.8 b/searchsummary/src/tests/docsumformat/parsetest/correct.8 new file mode 100644 index 00000000000..e929b872a05 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.8 @@ -0,0 +1,7 @@ +idtype integer + +class class_50 id 50 +field title type data + +class class_100 id 100 +field title type string diff --git a/searchsummary/src/tests/docsumformat/parsetest/correct.9 b/searchsummary/src/tests/docsumformat/parsetest/correct.9 new file mode 100644 index 00000000000..668505be77d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/correct.9 @@ -0,0 +1,13 @@ +idtype none + +class default id 0 +field f0 type integer +field f1 type short +field f2 type byte +field f3 type float +field f4 type double +field f5 type int64 +field f6 type string +field f7 type data +field f8 type longstring +field f9 type longdata diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.1 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.1 new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.1 diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.2 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.2 new file mode 100644 index 00000000000..600380f898d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.2 @@ -0,0 +1,14 @@ +idtype int + +class document id 1 +field title type string +field teaser type string +field url type string +field date type integer + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.3 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.3 new file mode 100644 index 00000000000..35d46b73f96 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.3 @@ -0,0 +1,14 @@ +idtype byte + +class document id 1 +field title type string +field teaser type string +field url type string +field date type integer + +class image id 1 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.4 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.4 new file mode 100644 index 00000000000..f50c143b4be --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.4 @@ -0,0 +1,14 @@ +idtype byte + +class document id 1 +field title type string +field teaser type string +field url type string +field date type int + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.5 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.5 new file mode 100644 index 00000000000..6579c30a29d --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.5 @@ -0,0 +1,14 @@ +idtype byte + +class document id 1 +field title type string +field teaser type string +field url type string +field url type integer + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.6 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.6 new file mode 100644 index 00000000000..2ce1ab9507e --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.6 @@ -0,0 +1,13 @@ +idtype byte + +field title type string +field teaser type string +field url type string +field date type integer + +class image id 2 +field title type string +field date type integer +field width type short +field height type short +field bitmaps type byte diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.7 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.7 new file mode 100644 index 00000000000..e51bb1d2d48 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.7 @@ -0,0 +1,14 @@ +STRING URL +STRING TITLE +STRING TITLE +INT DSHOST +INT DSKEY +INT BYTES +INT WORDS +INT MODDATE +INT CRAWLDATE +BYTE LANG1 +BYTE LANG2 +BYTE LANG3 +BYTE LANG4 +INT CHARSET diff --git a/searchsummary/src/tests/docsumformat/parsetest/incorrect.8 b/searchsummary/src/tests/docsumformat/parsetest/incorrect.8 new file mode 100644 index 00000000000..7639557b734 --- /dev/null +++ b/searchsummary/src/tests/docsumformat/parsetest/incorrect.8 @@ -0,0 +1,2 @@ +idtype byte +STRING TITLE |