001: /*
002: * $Id: IErrorCodes.java,v 1.43 2006/06/25 23:02:51 spal Exp $
003: * $Source: /cvsroot/sqlunit/sqlunit/src/net/sourceforge/sqlunit/IErrorCodes.java,v $
004: * SQLUnit - a test harness for unit testing database stored procedures.
005: * Copyright (C) 2003 The SQLUnit Team
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021: package net.sourceforge.sqlunit;
022:
023: /**
024: * This interface lists the generic error codes that are raised by SQLUnit.
025: * The documentation explains each of these errors in detail, including
026: * what corrective action to take.
027: * @author Sujit Pal (spal@users.sourceforge.net)
028: * @version $Revision: 1.43 $
029: */
030: public interface IErrorCodes {
031:
032: /**
033: * Returns the line feed character for the current system.
034: */
035: String LF = System.getProperty("line.separator");
036:
037: // ------------------ Input validation errors ----------------------------
038:
039: /**
040: * NO_TESTFILE.
041: * @sqlunit.error name="Input Test File not specified, specify testfile
042: * or fileset. {usage}"
043: * description="Neither the test file or a fileset (in the sqlunit Ant
044: * task) was specified to SQLUnit. This is a usage issue and the usage
045: * message that follows will indicate how to supply the XML file to
046: * SQLUnit"
047: */
048: String NO_TESTFILE = "Input Test File not specified, specify testfile or fileset."
049: + LF + "{0}";
050:
051: /**
052: * TESTFILE_NOT_FOUND.
053: * @sqlunit.error name="Test File {filename} not found. {usage}"
054: * description="The test file specified could not be found by SQLUnit.
055: * Check to see if the test file exists as specified on your operating
056: * system"
057: */
058: String TESTFILE_NOT_FOUND = "Cannot find Test File {0}" + LF
059: + "{1}";
060:
061: /**
062: * DUPLICATE_TESTFILE.
063: * @sqlunit.error name="Input Test File specified twice, specify either
064: * file or fileset"
065: * description="The test file name was specified both in the testfile
066: * attribute as well as the fileset nested element. Use one or the other,
067: * not both"
068: */
069: String DUPLICATE_TESTFILE = "Input Test File specified twice, specify either testfile or fileset";
070:
071: /**
072: * TESTFILE_CANT_READ.
073: * @sqlunit.error name="Cannot read Test File {filename}"
074: * description="SQLUnit does not have sufficient permissions to read
075: * the specified test file. Fix the permissions on the file at the
076: * operating system level"
077: */
078: String TESTFILE_CANT_READ = "Cannot read Test File {0}";
079:
080: /**
081: * CANT_BUILD_CONNECTION.
082: * @sqlunit.error name="Cannot build Connection (id={id}) because {reason}"
083: * description="SQLUnit could not build the Connection object with the
084: * properties supplied. Verify that the properties for building the
085: * Connection are valid."
086: */
087: String CANT_BUILD_CONNECTION = "Cannot build Connection (connection-id={0}) because {1}";
088:
089: /**
090: * MISSING_RESOURCE.
091: * @sqlunit.error name="{resource} not found in specified Context"
092: * description="SQLUnit could not find the named class or resource
093: * in the specified Context. The Context could be the system classpath,
094: * the path specified by the jarfile-url attribute if that is specified,
095: * or the Naming Context if Connection is being looked up from a JNDI
096: * server."
097: */
098: String MISSING_RESOURCE = "{0} not found in specified Context";
099:
100: /**
101: * NO_INCLUDE_FILE.
102: * @sqlunit.error name="Included file {filename} not found"
103: * description="The include file specified in the include tag in
104: * either the setup or teardown tags could not be found. Check to
105: * see if the file exists at the specified location on your operating
106: * system."
107: */
108: String NO_INCLUDE_FILE = "Included file {0} not found";
109:
110: /**
111: * ELEMENT_IS_NULL.
112: * @sqlunit.error name="System Error: Element {element} is null"
113: * description="This is a system error and means that there is a
114: * problem with the code. Log a bug against the SQLUnit project
115: * with details on how to reproduce it."
116: */
117: String ELEMENT_IS_NULL = "System Error: Element <{0}> is NULL";
118:
119: /**
120: * CONNECTION_IS_NULL.
121: * @sqlunit.error name="System Error: Connection {id} is null or
122: * incorrectly specified"
123: * description="This is a system error and means that there is a problem
124: * with the code. Log a bug against the SQLUnit project with details on
125: * how to reproduce it."
126: */
127: String CONNECTION_IS_NULL = "Connection({0}) is NULL or incorrectly specified";
128:
129: /**
130: * MATCHER_EXCEPTION.
131: * @sqlunit.error name="Match Exception in class: {classname},
132: * message: {exception_message}"
133: * description="This error message may be encountered when using a
134: * User-defined matcher class in conjunction with the diff tag. A
135: * Matcher class always throws this type of exception if it did not
136: * get the inputs it expected or if it encounters an unexpected
137: * exception at runtime. The exception_message provides more
138: * information as to what the problem is. Usually, it can be fixed
139: * by passign arguments correctly to the Matcher class."
140: */
141: String MATCHER_EXCEPTION = "Match Exception in class: {0}, message: {1}";
142:
143: /**
144: * MATCH_PATTERN_EXCEPTION.
145: * @sqlunit.error name="Cannot parse match pattern: {pattern}"
146: * description="The values for the resultset-id, row-id and col-id
147: * attributes to the Match tag can either be specified as exact
148: * numbers, a comma-separated enumeration or a range. It can also
149: * be omitted altogether or be specified as a *, both of which
150: * imply not to match against the particular filter. The error
151: * message means that the pattern was incorrectly specified or
152: * could not be parsed for some reason. The pattern will need to
153: * be modified to conform to the rules described above."
154: */
155: String MATCH_PATTERN_EXCEPTION = "Cannot parse match pattern: {1}";
156:
157: /**
158: * MATCHER_NOT_FOUND.
159: * @sqlunit.error name="Matcher class {className} not available in
160: * CLASSPATH"
161: * description="Some simple matchers are supplied as part of the
162: * SQLUnit package. Matchers can also be written by users in their
163: * own package and be referenced from the SQLUnit tests provided the
164: * user-written Matcher exists in the user's CLASSPATH. The message
165: * indicates that it is not. Modify the CLASSPATH to include the
166: * user-defined Matcher class."
167: */
168: String MATCHER_NOT_FOUND = "Matcher class {0} not available in the CLASSPATH";
169:
170: /**
171: * NO_USERMATCH_VALUE.
172: * @sqlunit.error name="No match on variable at [rset,row,col]=[
173: * {rset},{row},{col}] using class {matcher_class_name} expected:
174: * {expected_result} but got {actual_result}"
175: * description="This is a variation of the standard message reported
176: * in case of test failures. This message is reported only by the
177: * Diff tag since that is the only tag which allows user-defined
178: * matching. In addition to the information reported by the test
179: * failure, it also reports the class name of the Matcher class
180: * currently being used. Corrective action is to fix the test."
181: */
182: String NO_USERMATCH_VALUE = "No match on variable at [rset,row,col]=({0}"
183: + LF
184: + "*** using class: {1}"
185: + LF
186: + "*** expected:"
187: + LF
188: + "{2}" + LF + "*** but got:" + LF + "{3}" + LF + "{4}";
189:
190: /**
191: * IMPOSSIBLE_PARTIAL_MATCH
192: * @sqlunit.error name="Partial Match impossible at {position}: {reason}"
193: * description="Partial match at the specified position could not
194: * be done because of the reason specified."
195: */
196: String IMPOSSIBLE_PARTIAL_MATCH = "Partial Match impossible at {0}: {1}";
197:
198: // ------------------ Processing errors ----------------------------------
199:
200: /**
201: * UNSUPPORTED_DATATYPE_PARSE.
202: * @sqlunit.error name="At {position}, could not convert {actual_value}
203: * to {java_class_name} for {SQL_Type_Name}({SQL_Type})"
204: * description="The String value supplied in the param element could
205: * not be converted to the appropriate class dictated by the datatype
206: * mapping for that variable. You will most likely need to provide
207: * an override mapping specific to your database, or, if there is no
208: * suitable mapping, you/we could write a mapping class to handle
209: * this type."
210: */
211: String UNSUPPORTED_DATATYPE_PARSE = "At {0}, could not convert {1} to {2} for {3}({4})";
212:
213: /**
214: * UNSUPPORTED_DATATYPE_FORMAT.
215: * @sqlunit.error name="At {position}, could not convert {java_class_name}
216: * returned from database to {SQL_Type_Name}({SQL_Type})"
217: * description="The Object returned from the database is not of
218: * the same class that the class mapped to the SQL Type SQL_Type
219: * wraps. You will most likely need to provide an override mapping
220: * for your database, or, if there is no suitable mapping, you/we
221: * could write a mapping class to handle this type."
222: */
223: String UNSUPPORTED_DATATYPE_FORMAT = "At {0}, could not convert {1} returned from database to {2}({3})";
224:
225: /**
226: * UNSUPPORTED_DATATYPE.
227: * @sqlunit.error name="At {position}, datatype {SQL_Type_Name}({SQL_Type})
228: * is not supported"
229: * description="The specified datatype is one of the standard
230: * java.sql.Types but does not have an explicit mapping to a class.
231: * You will most likely need to provide an override mapping for your
232: * database based on your knowledge of the type, or, if there is no
233: * suitable mapping, you/we could write a mapping class to handle this
234: * type."
235: */
236: String UNSUPPORTED_DATATYPE = "At {0}, datatype {1}({2}) is not supported";
237:
238: /**
239: * UNDEFINED_TYPE.
240: * @sqlunit.error name="No type mapping found for (server.)type
241: * {{server_name}.{datatype}}"
242: * description="SQLUnit could not find a mapping type for this
243: * specified type name. This is a non-standard (not in java.sql.Types)
244: * datatype, for which an override needs to be set in the mapping
245: * file for your database in usertypes.properties. If none of the existing
246: * mapping classes seem suitable, then you/we may have to write
247: * a new mapping class and map this to the datatype."
248: */
249: String UNDEFINED_TYPE = "No type mapping found for (server.)type {0}";
250:
251: /**
252: * REPLACE_ERROR
253: * @sqlunit.error name="Parsing of {text} failed because {reason}"
254: * description="SQLUnit could not find the variable defined in
255: * the symbol table. If you do not mind missing variables, then
256: * you should set partialOk to true."
257: */
258: String REPLACE_ERROR = "Variable replacement of \"{0}\" failed because {1}";
259:
260: /**
261: * UNDEFINED_SYMBOL.
262: * @sqlunit.error name="The symbol could not be found in the symbol table"
263: * description="The named symbol could not be found. Check your logic
264: * and verify that you have set the symbol before trying to use it."
265: */
266: String UNDEFINED_SYMBOL = "Symbol {0} is not defined in the symbol table";
267:
268: /**
269: * UNDEFINED_PARAM.
270: * @sqlunit.error name="Parameter {parameter_name} is not defined"
271: * description="The named parameter appears in the subdef as unspecified,
272: * but was not specified in the corresponding sub."
273: */
274: String UNDEFINED_PARAM = "Parameter {0} is not defined";
275:
276: /**
277: * ERROR_IN_INCLUDE.
278: * @sqlunit.error name="Statement {statement} ({number}) in include
279: * file {filename} returned result {error_code}"
280: * description="A SQL Statement in the include file referenced by the
281: * file name failed with the given error code. The SQL statements are
282: * indexed starting at 1."
283: */
284: String ERROR_IN_INCLUDE = "Statement \"{0}\" ({1}) in include file {2} returned error: {3}";
285:
286: /**
287: * INVALID_VARIABLE_NAME_FORMAT.
288: * @sqlunit.error name="Variable {variable_name} is invalid, should be
289: * in the format \${variable_name}"
290: * description="SQLUnit only accepts variables in the format
291: * ${variable_name}. Fix the name in the XML input file."
292: */
293: String INVALID_VARIABLE_NAME_FORMAT = "Variable name {0} is invalid, should be in the format ${varname}";
294:
295: /**
296: * IS_A_CURSOR.
297: * @sqlunit.error name="Value at outparam id={id} is a CURSOR, not a
298: * {supplied_type}"
299: * description="The type specified in the param declaration for a stored
300: * procedure or SQL statement was incorrect. Fix the type in the XML
301: * input file."
302: */
303: String IS_A_CURSOR = "Value at outparam id={0} is a CURSOR, not a {1}";
304:
305: /**
306: * IS_A_STRUCT.
307: * @sqlunit.error name="Value at outparam id={id} is a STRUCT, not a
308: * {supplied_type}"
309: * description="The type specified in the param declaration for a stored
310: * procedure or SQL statement was incorrect. Fix the type in the XML
311: * input file."
312: */
313: String IS_A_STRUCT = "Value at outparam id={0} is a STRUCT, not a {1}";
314:
315: /**
316: * NOT_A_NUMBER.
317: * @sqlunit.error name="Value {supplied_value} for {variable} could not
318: * be converted to a numeric value"
319: * description="SQLUnit expects a numeric value at the location
320: * indicated, but parsing it from its String value to the appropriate
321: * numeric value resulted in a NumberFormatException."
322: */
323: String NOT_A_NUMBER = "Value {0} for {1} could not be converted to a numeric value";
324:
325: /**
326: * ERROR_DIGESTING_DATA.
327: * @sqlunit.error name="Could not convert to digest because {reason}"
328: * description="The reason will give more information as to why the
329: * digestion process failed. Large Objects such as BLOBs and CLOBs
330: * are digested and then compared with specified MD5 Checksums of files
331: * or the MD5 Checksum itself. If Java Object Support is enabled, and
332: * the large object represents a Serializable Java Object, or the
333: * datatype of the LOB is JAVA_OBJECT, then the object's toString()
334: * method will be called and the results returned."
335: */
336: String ERROR_DIGESTING_DATA = "Could not convert to digest because {0}";
337:
338: /**
339: * METHOD_INVOCATION_ERROR.
340: * @sqlunit.error name="Cannot invoke method {className}.{methodName}"
341: * description="This will usually be encountered when using the
342: * methodinvoker or dynamicsql tags, which depend on the results of
343: * invoking a specified method in a specified class in the CLASSPATH.
344: * The error will identify where the problem is happening, and will
345: * also include the error stack trace within the exception. To get
346: * the stack trace, rerun the test with debug set to true, and fix
347: * the problem that is causing this error to appear."
348: */
349: String METHOD_INVOCATION_ERROR = "Cannot invoke method {0}.{1}";
350:
351: // ------------------ Test output errors ---------------------------------
352:
353: /**
354: * NO_ASSERT_METHOD.
355: * @sqlunit.error name="Assertion {assert} is not supported"
356: * description="The assertion provided in the assert attribute for
357: * this test element is not supported. Please check the documentation
358: * for a list of supported assertions."
359: */
360: String NO_ASSERT_METHOD = "Assertion \"{0}\" is not supported";
361:
362: /**
363: * ASSERT_FAILED.
364: * @sqlunit.error name="Assertion {assert} failed ({reason}), expected
365: * {expected_result}, but got {actual_result}, {failure_message}"
366: * description="The specified assertion failed."
367: */
368: String ASSERT_FAILED = "Assertion \"{0}\" failed {1}" + LF
369: + "*** expected:" + LF + "{2}" + LF + "*** but got:" + LF
370: + "{3}" + LF + "{4}";
371:
372: /**
373: * ASSERT_UNACCEPTABLE_ELAPSED_TIME.
374: * @sqlunit.error name="Expected to complete in {expected-duration}
375: * ms +/- {percent-tolerance}%, but took {actual_duration}ms"
376: * description="The test took either too little or too much time
377: * compared with the specified expected time. If the percent tolerance
378: * is provided for the test, then SQLUnit will check for specified
379: * time +/- the tolerance, else it will use a default tolerance of
380: * 10%. If it is taking too much time, it is possible that your
381: * new implementation is not using all the optimizations that your
382: * old implementation was taking advantage of. If it is taking too
383: * little time, it is possible that your stored procedure is using
384: * better optimizations or not doing everything it should. It could
385: * also be that your expected durations are now incorrect because of
386: * server-level tuning, or that the JVM is overloaded. There could
387: * be other causes for this discrepancy which are not covered here,
388: * which may be related to your site."
389: */
390: String ASSERT_UNACCEPTABLE_ELAPSED_TIME = "Expected to complete in {0}ms +/- {1}%, but took {2}ms";
391:
392: /**
393: * TEST_FAILURE_EXCEPTION.
394: * @sqlunit.error name="SQLUnit Tests failed, file {filename}, run:
395: * {total_tests_run}, failures: {number_of_failed_tests}, errors:
396: * {number_of_errors_encountered}"
397: * description="This message is reported at the end of each SQLUnit
398: * test file if there was an error or failure running the tests in the
399: * file."
400: */
401: String TEST_FAILURE_EXCEPTION = "SQLUnit Tests Failed: {0}";
402:
403: /**
404: * SUITE_FAILURE_EXCEPTION.
405: * @sqlunit.error name="One or more SQLUnit Tests failed, see the
406: * {console|logfile} for details"
407: * description="This message is reported at the end of an SQLUnit run,
408: * spanning one or more test files, if there was a failure or an error
409: * in any one of the tests. The output will describe the exact nature of
410: * the failure(s)."
411: */
412: String SUITE_FAILURE_EXCEPTION = "One or more SQLUnit Tests failed, see {0} for details";
413:
414: // --------------------- System Errors -------------------------------
415:
416: /**
417: * GENERIC_ERROR.
418: * @sqlunit.error name="{Type} error ({Exception_Class}): {message}"
419: * description="The entire error message is returned, usually from
420: * the JVM. The exception class specifies the Exception class name.
421: * Log a bug against the SQLUnit project if the meaning is
422: * not clear enough, otherwise take the necessary action to fix the
423: * condition that is causing it. Turning on the debug attribute for
424: * the sqlunit ant task will also show the stack trace for reporting
425: * or for analysis."
426: */
427: String GENERIC_ERROR = "{0} error ({1}): {2}";
428:
429: // -------------------- Usage ------------------------------------------
430:
431: /**
432: * Usage string.
433: */
434: String USAGE = "Usage:" + LF + "<target name=\"test_target_name\">"
435: + LF + " <sqlunit (testFile=\"test_file_name\")*" + LF
436: + " (haltOnFailure=\"true\"|\"false\")*" + LF
437: + " (debug=\"true\"|\"false\")*>" + LF
438: + " (<fileSet>" + LF
439: + " <include name=\"filename pattern to match\" />"
440: + LF
441: + " <exclude name=\"filename pattern to exclude\" />"
442: + LF + " </fileSet>)*" + LF + " </sqlunit>" + LF
443: + "</target>";
444:
445: /**
446: * A pseudo-method inserted here to keep Bloch happy. We are not about
447: * to implement this class anytime soon, so there is no danger with
448: * doing this here. We would rather have this inconsistency than give
449: * up the checkstyle check for the other interfaces, which do satisfy
450: * this criterion.
451: * @return a String.
452: */
453: String getUsage();
454: }
|