int analyzeError (const Specification &lSpec, const TestDiagnosticHandler& errHandler) { if (isErrorExpected(errHandler, &lSpec)) { printErrors(errHandler, "The following execution error occurred as expected", false); return EXPECTED_ERROR; } else { printErrors(errHandler, "Unexpected error executing query", false); std::cout << "Expected error(s):"; for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin(); lIter != lSpec.errorsEnd(); ++lIter) { std::cout << " " << *lIter; } if (lSpec.errorsSize () == 0) { std::cout << " (none)"; } std::cout << std::endl; return UNEXPECTED_ERROR; } }
main(int argc, char** argv) #endif { if (argc != 2) { std::cout << "\nusage: testdriver [testfile]" << std::endl; return 1; } zorba::Zorba* engine = zorba::Zorba::getInstance(zorba::StoreManager::getStore()); zorba::XmlDataManager_t xmlDataMgr = engine->getXmlDataManager(); Specification lSpec; /* * Sanitize paths */ std::string srcDir = zorba::fs::normalize_path(zorba::UPDATE_SRC_DIR); std::string binDir = zorba::fs::normalize_path(zorba::UPDATE_BINARY_DIR); std::string argString = zorba::fs::normalize_path(std::string(argv[1])); std::string lSpecNoSuffix = argString.substr(0, argString.size()-5); std::string lSpecFile( srcDir ); zorba::fs::append( lSpecFile, "Queries" ); zorba::fs::append(lSpecFile, argString); std::string lSpecPath( zorba::fs::dir_name( lSpecFile ) ); if ( zorba::fs::get_type( lSpecFile ) != zorba::fs::file ) { std::cout << "\n spec file " << lSpecFile << " does not exist or is not a file" << std::endl; return 2; } std::cout << "test " << lSpecNoSuffix << std::endl; std::string lResultFile( binDir ); zorba::fs::append( lResultFile, "QueryResults" ); zorba::fs::append( lResultFile, lSpecNoSuffix ); lResultFile += ".res"; std::string lRefFile( srcDir ); zorba::fs::append( lRefFile, "ExpectedTestResults" ); zorba::fs::append( lRefFile, lSpecNoSuffix ); lRefFile += ".xml.res"; std::string lRefPath( zorba::fs::dir_name( lRefFile ) ); // read the xargs and errors if the spec file exists lSpec.parseFile(lSpecFile); Zorba_SerializerOptions lSerOptions; lSerOptions.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES; std::unique_ptr<zorba::TestSchemaURIMapper> smapper; ulong numQueries = (ulong)lSpec.theStates.size(); // // For each query in the spec file // for(ulong curQuery = 0; curQuery < numQueries; ++curQuery) { State* lState = lSpec.theStates[curQuery]; zorba::XQuery_t lQuery; // // Open the query file // std::string qname_str; if(lSpecPath.find("XQueryX") == std::string::npos) qname_str = lState->theName + ".xq"; else qname_str = lState->theName + ".xqx"; std::cout << "query name = " << qname_str << std::endl; std::string lQueryFile(lSpecPath); zorba::fs::append( lQueryFile, qname_str ); std::cout << std::endl << "Query (Run " << curQuery+1 << "):" << std::endl; std::cout << "Query file " << lQueryFile << ": " << std::endl; zorba::printFile(std::cout, lQueryFile); std::cout << std::endl; std::ifstream lQueryStream(lQueryFile.c_str()); // // Create static context and set it up. // Create and compile the query object. // try { zorba::StaticContext_t lContext = engine->createStaticContext(); std::string path = lQueryFile; if (path.find("w3c_update_testsuite") != std::string::npos) { lContext->setXQueryVersion(zorba::xquery_version_1_0); std::string uri_map_file = zorba::fs::normalize_path(srcDir + "/Queries/w3c_update_testsuite/TestSources/uri.txt"); smapper.reset(new zorba::TestSchemaURIMapper( uri_map_file.c_str() )); lContext->registerURIMapper( smapper.get() ); zorba::Item lEnable = engine->getItemFactory()-> createQName("http://zorba.io/options/features", "", "enable"); zorba::Item lDisable = engine->getItemFactory()-> createQName("http://zorba.io/options/features", "", "disable"); lContext->declareOption(lDisable, "scripting"); #if 1 if (path.find("Val") != std::string::npos) lContext->setBoundarySpacePolicy(zorba::preserve_space); #endif #if 1 zorba::String lProlog = zorba::String(std::string("import schema 'http://www.w3.org/XML/1998/namespace';\n")); lContext->loadProlog(lProlog, getCompilerHints()); #endif } lQuery = engine->createQuery(); lQuery->setFileName (lQueryFile.c_str()); lQuery->compile(lQueryStream, lContext, getCompilerHints()); #ifdef ZORBA_TEST_PLAN_SERIALIZATION int save_retval; if((save_retval = save_load_plan(engine, lQuery, smapper.get(), lResultFile))) { return save_retval; } #endif } catch (zorba::ZorbaException &e) { if (isErrorExpected(e, lState)) { std::cout << "Expected compiler error:\n" << e << std::endl; std::cout << "updtestdriver: success" << std::endl; return 0; } else { std::cout << "Unexpected compiler error:\n" << e << std::endl; return 3; } } // // // try { zorba::DynamicContext* lDynCtx = lQuery->getDynamicContext(); if (lState->hasDate) { std::string lDateTime = lState->theDate; if (lDateTime.find("T") == std::string::npos) { lDateTime += "T00:00:00"; } lDynCtx->setCurrentDateTime(engine->getItemFactory()->createDateTime(lDateTime)); } std::vector<Variable*>::const_iterator lVarIter = lState->varsBegin(); std::vector<Variable*>::const_iterator lVarEnd = lState->varsEnd(); for(; lVarIter != lVarEnd; ++lVarIter) { Variable* lVar = *lVarIter; set_var( lVar->theInline, lVar->theName, lVar->theValue, xmlDataMgr.get(), lQuery->getStaticContext(), lDynCtx); } } catch (zorba::ZorbaException &e) { if (isErrorExpected(e, lState)) { std::cout << "Expected execution error:\n" << e << std::endl; continue; } else { std::cout << "Unexpected execution error:\n" << e << std::endl; return 6; } } // // // try { zorba::fs::remove( lResultFile, true ); std::ofstream lResFileStream(lResultFile.c_str()); lQuery->execute(lResFileStream, &lSerOptions); lResFileStream.flush(); if (lState->hasCompare) { bool lRes = false; bool anyMatch = false; ulong numRefs = (ulong)lState->theCompares.size(); for (ulong i = 0; i < numRefs && !lRes; i++) { std::string lRefFileTmpString = lRefPath; // the ref file is the same for xqueryx and xquery tests // hence, we remove the string xqueryx or xquery from the path size_t lPosOfW3C = lRefPath.find("w3c_update_testsuite"); if (lPosOfW3C != std::string::npos) { if (lRefPath.find("XQueryX", lPosOfW3C) != std::string::npos) lRefFileTmpString = lRefFileTmpString.erase(lPosOfW3C + 21, 8); else lRefFileTmpString = lRefFileTmpString.erase(lPosOfW3C + 21, 7); } std::string lRefFile( lRefFileTmpString ); zorba::fs::append( lRefFile, lState->theCompares[i] ); std::cout << std::endl << "Ref " << lRefFile << std::endl; int lLine, lCol; std::string lRefLine, lResultLine; lRes = zorba::fileEquals(lRefFile.c_str(), lResultFile.c_str(), lLine, lCol, lRefLine, lResultLine); // if the simple comparison doesn't work, we do the full-fledged // xml canonical comparison if (lRes) { std::cout << std::endl; std::cout << "updtestdriver: success (non-canonical result matches)" << std::endl; anyMatch = true; break; } else { std::cout << std::endl; std::cout << "Actual and Reference results are not identical" << std::endl << std::endl << "Actual Result " << lResultFile << ": " << std::endl << std::endl; zorba::printFile(std::cout, lResultFile); std::cout << std::endl << "Reference Result " << lRefFile << ": " << std::endl << std::endl; zorba::printFile(std::cout, lRefFile); std::cout << std::endl << std::endl; int lCanonicalRes = zorba::canonicalizeAndCompare(State::compareTypeStr(lState->theCompareTypes[i]), lRefFile.c_str(), lResultFile.c_str()); if (lCanonicalRes == 0) { anyMatch = true; break; } } } // multiple compare possible if (!anyMatch) { return 4; } } else if (lState->hasErrors && curQuery == numQueries-1) { std::cout << std::endl; std::cout << "Query must throw an error!" << std::endl; return 5; } else { std::cout << std::endl; std::cout << "Query returns result but no expected result defined!" << std::endl; zorba::printFile(std::cout, lResultFile); } } catch (zorba::ZorbaException &e) { if (isErrorExpected(e, lState)) { std::cout << std::endl; std::cout << "Expected execution error:\n" << e << std::endl; continue; } else { std::cout << std::endl; std::cout << "Unexpected execution error:\n" << e << std::endl; return 6; } } } // for each query described in the spec file std::cout << std::endl; std::cout << "updtestdriver: success" << std::endl; return 0; }