config_result_check.cc 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <cc/command_interpreter.h>
  15. #include <dhcpsrv/testutils/config_result_check.h>
  16. #include <boost/algorithm/string/classification.hpp>
  17. #include <boost/algorithm/string/constants.hpp>
  18. #include <boost/algorithm/string/split.hpp>
  19. #include <string>
  20. namespace isc {
  21. namespace dhcp {
  22. namespace test {
  23. using namespace isc;
  24. using namespace isc::data;
  25. bool errorContainsPosition(ConstElementPtr error_element,
  26. const std::string& file_name) {
  27. if (error_element->contains(isc::config::CONTROL_RESULT)) {
  28. ConstElementPtr result = error_element->get(isc::config::CONTROL_RESULT);
  29. ConstElementPtr text = error_element->get(isc::config::CONTROL_TEXT);
  30. if (!result || (result->getType() != Element::integer) || !text
  31. || (text->getType() != Element::string)) {
  32. return (false);
  33. }
  34. // Get the error message in the textual format.
  35. std::string error_string = text->stringValue();
  36. // The position of the data element causing an error has the following
  37. // format: <filename>:<linenum>:<pos>. The <filename> has been specified
  38. // by a caller, so let's first check if this file name is present in the
  39. // error message.
  40. size_t pos = error_string.find(file_name);
  41. // If the file name is present, check that it is followed by the line
  42. // number and position within the line.
  43. if (pos != std::string::npos) {
  44. // Split the string starting at the begining of the <filename>. It
  45. // should return a vector of strings.
  46. std::string sub = error_string.substr(pos);
  47. std::vector<std::string> split_pos;
  48. boost::split(split_pos, sub, boost::is_any_of(":"),
  49. boost::algorithm::token_compress_off);
  50. // There should be at least three elements: <filename>, <linenum>
  51. // and <pos>. There can be even more, because one error string may
  52. // contain more positions of data elements for multiple
  53. // configuration nesting levels. We want at least one position.
  54. if ((split_pos.size() >= 3) && (split_pos[0] == file_name) &&
  55. (!split_pos[1].empty()) && !(split_pos[2].empty())) {
  56. // Make sure that the line number comprises only digits.
  57. for (int i = 0; i < split_pos[1].size(); ++i) {
  58. if (!isdigit(split_pos[1][i])) {
  59. return (false);
  60. }
  61. }
  62. // Go over digits of the position within the line.
  63. int i = 0;
  64. while (isdigit(split_pos[2][i])) {
  65. ++i;
  66. }
  67. // Make sure that there has been at least one digit and that the
  68. // position is followed by the paren.
  69. if ((i == 0) || (split_pos[2][i] != ')')) {
  70. return (false);
  71. }
  72. // All checks passed.
  73. return (true);
  74. }
  75. }
  76. }
  77. return (false);
  78. }
  79. }
  80. }
  81. }