/*************************************************************************\ * Copyright (c) 2019 Michael Davidsaver * SPDX-License-Identifier: EPICS * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { void findTestData() { const char *locations[] = { ".", "..", ".." OSI_PATH_LIST_SEPARATOR "O.Common", "O.Common", }; for(size_t i=0; i %d", expect ? "ran" : "expected error from", fname, err); } void testCmd(const char *cmd, bool expect=true) { testDiag("eval \"%s\"", cmd); int err = iocshCmd(cmd); testOk((err==0) ^ (!expect), "%s \"%s\" -> %d", expect ? "eval'd" : "expected error from", cmd, err); } std::set reached; const iocshArg positionArg0 = {"position", iocshArgString}; const iocshArg * const positionArgs[1] = { &positionArg0 }; const iocshFuncDef positionFuncDef = {"position",1,positionArgs}; void positionCallFunc(const iocshArgBuf *args) { testDiag("Reaching \"%s\"", args[0].sval); reached.insert(args[0].sval); } void testPosition(const std::string& pos, bool expect=true) { testOk((reached.find(pos)!=reached.end()) ^ !expect, "%sreached position %s", expect ? "" : "not ", pos.c_str()); } const iocshArg assertArg0 = {"condition", iocshArgInt}; const iocshArg * const assertArgs[1] = {&assertArg0}; const iocshFuncDef assertFuncDef = {"assert",1,assertArgs}; void assertCallFunc(const iocshArgBuf *args) { iocshSetError(args[0].ival); } const iocshFuncDef testHelpFunction1Def = {"testHelpFunction1",0,0, "Usage message of testHelpFunction1\n"}; const iocshFuncDef testHelpFunction2Def = {"testHelpFunction2",0,0, "Usage message of testHelpFunction2\n"}; const iocshFuncDef testHelpFunction3Def = {"testHelpFunction3",0,0, "Usage message of testHelpFunction3\n"}; void doNothing(const iocshArgBuf *args) { return; } std::string readFile(std::string filename) { std::ifstream t(filename.c_str()); std::stringstream buffer; if (!t.is_open()) { throw std::invalid_argument("Could not open filename " + filename); } buffer << t.rdbuf(); return buffer.str(); } bool compareFiles(const std::string& p1, const std::string& p2) { std::ifstream f1(p1.c_str(), std::ifstream::binary|std::ifstream::ate); std::ifstream f2(p2.c_str(), std::ifstream::binary|std::ifstream::ate); if (f1.fail() || f2.fail()) { testDiag("One or more files failed to open"); testDiag("f1.fail(): %d f2.fail(): %d", f1.fail(), f2.fail()); return false; // File problem } if (f1.tellg() != f2.tellg()) { testDiag("File sizes did not match"); return false; // Size mismatch } // Seek back to beginning and use std::equal to compare contents f1.seekg(0, std::ifstream::beg); f2.seekg(0, std::ifstream::beg); bool are_equal = std::equal( std::istreambuf_iterator(f1.rdbuf()), std::istreambuf_iterator(), std::istreambuf_iterator(f2.rdbuf()) ); if (! are_equal) { testDiag("File contents did not match"); std::string line; f1.seekg(0, std::ifstream::beg); f2.seekg(0, std::ifstream::beg); testDiag("File1 contents: "); while(std::getline(f1, line)) { testDiag("%s", line.c_str()); } testDiag("File2 contents: "); while(std::getline(f2, line)) { testDiag("%s", line.c_str()); } } return are_equal; } void testHelp(void) { testDiag("iocshTest testHelp start"); // Filename to save help output to const std::string filename = "testHelpOutput"; // Verify help lists expected commands iocshCmd(("help > " + filename).c_str()); std::string contents = readFile(filename); testOk1(contents.find("help") != std::string::npos); testOk1(contents.find("testHelpFunction1") != std::string::npos); testOk1(contents.find("testHelpFunction2") != std::string::npos); testOk1(contents.find("testHelpFunction3") != std::string::npos); // Confirm formatting of a single command iocshCmd(("help testHelpFunction1 > " + filename).c_str()); testOk1(compareFiles(filename, "iocshTestHelpFunction1") == true); // Confirm formatting of multiple commands iocshCmd(("help testHelp* > " + filename).c_str()); testOk1(compareFiles(filename, "iocshTestHelpFunctions") == true); remove(filename.c_str()); } } // namespace MAIN(iocshTest) { testPlan(25); libComRegister(); iocshRegister(&positionFuncDef, &positionCallFunc); iocshRegister(&assertFuncDef, &assertCallFunc); iocshRegister(&testHelpFunction1Def, &doNothing); iocshRegister(&testHelpFunction2Def, &doNothing); iocshRegister(&testHelpFunction3Def, &doNothing); findTestData(); testFile("iocshTestSuccess.cmd"); testPosition("success"); reached.clear(); testPosition("success", false); testCmd("