PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/subversion/tests/libsvn_subr/error-test.c

#
C | 246 lines | 169 code | 32 blank | 45 comment | 22 complexity | 9d1ace5ad18ff80e19faf5a52308ca45 MD5 | raw file
Possible License(s): Apache-2.0, CC-BY-SA-3.0, BSD-3-Clause, LGPL-2.0
  1. /*
  2. * error-test.c -- test the error functions
  3. *
  4. * ====================================================================
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. * ====================================================================
  22. */
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <apr_general.h>
  26. #include "svn_error_codes.h"
  27. #include "svn_error.h"
  28. #include "private/svn_error_private.h"
  29. #include "../svn_test.h"
  30. static svn_error_t *
  31. test_error_root_cause(apr_pool_t *pool)
  32. {
  33. apr_status_t secondary_err_codes[] = { SVN_ERR_STREAM_UNRECOGNIZED_DATA,
  34. SVN_ERR_STREAM_MALFORMED_DATA };
  35. apr_status_t root_cause_err_code = SVN_ERR_STREAM_UNEXPECTED_EOF;
  36. int i;
  37. svn_error_t *err, *root_err;
  38. /* Nest several errors. */
  39. err = svn_error_create(root_cause_err_code, NULL, "root cause");
  40. for (i = 0; i < 2; i++)
  41. err = svn_error_create(secondary_err_codes[i], err, NULL);
  42. /* Verify that the error is detected at the proper location in the
  43. error chain. */
  44. root_err = svn_error_root_cause(err);
  45. if (root_err == NULL)
  46. {
  47. svn_error_clear(err);
  48. return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
  49. "svn_error_root_cause failed to locate any "
  50. "root error in the chain");
  51. }
  52. for (i = 0; i < 2; i++)
  53. {
  54. if (root_err->apr_err == secondary_err_codes[i])
  55. {
  56. svn_error_clear(err);
  57. return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
  58. "svn_error_root_cause returned the "
  59. "wrong error from the chain");
  60. }
  61. }
  62. if (root_err->apr_err != root_cause_err_code)
  63. {
  64. svn_error_clear(err);
  65. return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
  66. "svn_error_root_cause failed to locate the "
  67. "correct error from the chain");
  68. }
  69. svn_error_clear(err);
  70. return SVN_NO_ERROR;
  71. }
  72. static svn_error_t *
  73. test_error_purge_tracing(apr_pool_t *pool)
  74. {
  75. svn_error_t *err, *err2, *child;
  76. if (SVN_NO_ERROR != svn_error_purge_tracing(SVN_NO_ERROR))
  77. return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
  78. "svn_error_purge_tracing() didn't return "
  79. "SVN_NO_ERROR after being passed a "
  80. "SVN_NO_ERROR.");
  81. err = svn_error_trace(svn_error_create(SVN_ERR_BASE, NULL, "root error"));
  82. #ifdef SVN_ERR__TRACING
  83. if (! svn_error__is_tracing_link(err))
  84. {
  85. return svn_error_create(SVN_ERR_TEST_FAILED, err,
  86. "The top error is not a tracing link:");
  87. }
  88. #endif
  89. err = svn_error_trace(svn_error_create(SVN_ERR_BASE, err, "other error"));
  90. #ifdef SVN_ERR__TRACING
  91. if (! svn_error__is_tracing_link(err))
  92. {
  93. return svn_error_create(SVN_ERR_TEST_FAILED, err,
  94. "The top error is not a tracing link:");
  95. }
  96. #endif
  97. err2 = svn_error_purge_tracing(err);
  98. for (child = err2; child; child = child->child)
  99. if (svn_error__is_tracing_link(child))
  100. {
  101. return svn_error_create(SVN_ERR_TEST_FAILED, err,
  102. "Tracing link found after purging the "
  103. "following chain:");
  104. }
  105. svn_error_clear(err);
  106. #ifdef SVN_ERR__TRACING
  107. /* Make an error chain containing only tracing errors and check that
  108. svn_error_purge_tracing() asserts on it. */
  109. {
  110. svn_error_t err_copy;
  111. svn_error_malfunction_handler_t orig_handler;
  112. /* For this test, use a random error status. */
  113. err = svn_error_create(SVN_ERR_BAD_UUID, NULL, "");
  114. err = svn_error_trace(err);
  115. err->child->message = err->message;
  116. /* Register a malfunction handler that doesn't call abort() to
  117. check that a new error chain with an assertion error is
  118. returned. */
  119. orig_handler =
  120. svn_error_set_malfunction_handler(svn_error_raise_on_malfunction);
  121. err2 = svn_error_purge_tracing(err);
  122. svn_error_set_malfunction_handler(orig_handler);
  123. err_copy = *err;
  124. if (err2)
  125. {
  126. /* If err2 does share the same pool as err, then make a copy
  127. of err2 and err3 before err is cleared. */
  128. svn_error_t err2_copy = *err2;
  129. svn_error_t *err3 = err2;
  130. svn_error_t err3_copy;
  131. while (err3 && svn_error__is_tracing_link(err3))
  132. err3 = err3->child;
  133. if (err3)
  134. err3_copy = *err3;
  135. else
  136. err3_copy.apr_err = APR_SUCCESS;
  137. svn_error_clear(err);
  138. /* The returned error is only safe to clear if this assertion
  139. holds, otherwise it has the same pool as the original
  140. error. */
  141. SVN_TEST_ASSERT(err_copy.pool != err2_copy.pool);
  142. svn_error_clear(err2);
  143. SVN_TEST_ASSERT(err3);
  144. SVN_TEST_ASSERT(SVN_ERROR_IN_CATEGORY(err2_copy.apr_err,
  145. SVN_ERR_MALFUNC_CATEGORY_START));
  146. SVN_TEST_ASSERT(err3_copy.apr_err == err2_copy.apr_err);
  147. SVN_TEST_ASSERT(
  148. SVN_ERR_ASSERTION_ONLY_TRACING_LINKS == err3_copy.apr_err);
  149. }
  150. else
  151. {
  152. svn_error_clear(err);
  153. SVN_TEST_ASSERT(err2);
  154. }
  155. }
  156. #endif
  157. return SVN_NO_ERROR;
  158. }
  159. static svn_error_t *
  160. test_error_symbolic_name(apr_pool_t *pool)
  161. {
  162. struct {
  163. svn_errno_t errcode;
  164. const char *errname;
  165. } errors[] = {
  166. { SVN_ERR_BAD_CONTAINING_POOL, "SVN_ERR_BAD_CONTAINING_POOL" },
  167. { SVN_ERR_BAD_FILENAME, "SVN_ERR_BAD_FILENAME" },
  168. { SVN_ERR_XML_ATTRIB_NOT_FOUND, "SVN_ERR_XML_ATTRIB_NOT_FOUND" },
  169. { SVN_ERR_ENTRY_NOT_FOUND, "SVN_ERR_ENTRY_NOT_FOUND" },
  170. { SVN_ERR_ENTRY_CATEGORY_START + 1, NULL }, /* unused slot */
  171. { SVN_ERR_ENTRY_EXISTS, "SVN_ERR_ENTRY_EXISTS" },
  172. { SVN_ERR_ASSERTION_ONLY_TRACING_LINKS, "SVN_ERR_ASSERTION_ONLY_TRACING_LINKS" },
  173. { SVN_ERR_FS_CORRUPT, "SVN_ERR_FS_CORRUPT" },
  174. /* The following two error codes can return either of their names
  175. as the string. For simplicity, test what the current implementation
  176. returns; but if it starts returning "SVN_ERR_WC_NOT_DIRECTORY",
  177. that's fine (and permitted by the API contract). */
  178. { SVN_ERR_WC_NOT_DIRECTORY, "SVN_ERR_WC_NOT_WORKING_COPY" },
  179. { SVN_ERR_WC_NOT_WORKING_COPY, "SVN_ERR_WC_NOT_WORKING_COPY" },
  180. /* Test an implementation detail. */
  181. { SVN_ERR_BAD_CATEGORY_START, "SVN_ERR_BAD_CONTAINING_POOL" },
  182. #ifdef SVN_DEBUG
  183. { ENOENT, "ENOENT" },
  184. { APR_ENOPOOL, "APR_ENOPOOL" },
  185. #endif
  186. /* Test non-errors. */
  187. { -1, NULL },
  188. { SVN_ERR_WC_CATEGORY_START - 1, NULL },
  189. /* Whitebox-test exceptional cases. */
  190. { SVN_WARNING, "SVN_WARNING" },
  191. { 0, "SVN_NO_ERROR" }
  192. /* No sentinel. */
  193. };
  194. int i;
  195. for (i = 0; i < sizeof(errors) / sizeof(errors[0]); i++)
  196. SVN_TEST_STRING_ASSERT(svn_error_symbolic_name(errors[i].errcode),
  197. errors[i].errname);
  198. return SVN_NO_ERROR;
  199. }
  200. /* The test table. */
  201. static int max_threads = 1;
  202. static struct svn_test_descriptor_t test_funcs[] =
  203. {
  204. SVN_TEST_NULL,
  205. SVN_TEST_PASS2(test_error_root_cause,
  206. "test svn_error_root_cause"),
  207. SVN_TEST_PASS2(test_error_purge_tracing,
  208. "test svn_error_purge_tracing"),
  209. SVN_TEST_PASS2(test_error_symbolic_name,
  210. "test svn_error_symbolic_name"),
  211. SVN_TEST_NULL
  212. };
  213. SVN_TEST_MAIN