diff options
Diffstat (limited to '')
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/ctest.h | 321 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/datamap.h | 140 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/testdata.h | 113 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/testlog.h | 62 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/testtype.h | 40 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/tstdtmod.h | 117 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/uperf.h | 200 | ||||
-rw-r--r-- | intl/icu/source/tools/ctestfw/unicode/utimer.h | 282 |
8 files changed, 1275 insertions, 0 deletions
diff --git a/intl/icu/source/tools/ctestfw/unicode/ctest.h b/intl/icu/source/tools/ctestfw/unicode/ctest.h new file mode 100644 index 0000000000..da75be55b2 --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/ctest.h @@ -0,0 +1,321 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ******************************************************************************** + * + * Copyright (C) 1996-2013, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************** + */ + +#ifndef CTEST_H +#define CTEST_H + +#include "unicode/testtype.h" +#include "unicode/utrace.h" + + +/* prototypes *********************************/ + +U_CDECL_BEGIN +typedef void (U_CALLCONV *TestFunctionPtr)(void); +typedef int (U_CALLCONV *ArgHandlerPtr)(int arg, int argc, const char* const argv[], void *context); +typedef struct TestNode TestNode; +U_CDECL_END + +/** + * This is use to set or get the option value for REPEAT_TESTS. + * Use with set/getTestOption(). + * + * @internal + */ +#define REPEAT_TESTS_OPTION 1 + +/** + * This is use to set or get the option value for VERBOSITY. + * When option is set to zero to disable log_verbose() messages. + * Otherwise nonzero to see log_verbose() messages. + * Use with set/getTestOption(). + * + * @internal + */ +#define VERBOSITY_OPTION 2 + +/** + * This is use to set or get the option value for ERR_MSG. + * Use with set/getTestOption(). + * + * @internal + */ +#define ERR_MSG_OPTION 3 + +/** + * This is use to set or get the option value for QUICK. + * When option is zero, disable some of the slower tests. + * Otherwise nonzero to run the slower tests. + * Use with set/getTestOption(). + * + * @internal + */ +#define QUICK_OPTION 4 + +/** + * This is use to set or get the option value for WARN_ON_MISSING_DATA. + * When option is nonzero, warn on missing data. + * Otherwise, errors are propagated when data is not available. + * Affects the behavior of log_dataerr. + * Use with set/getTestOption(). + * + * @see log_data_err + * @internal + */ +#define WARN_ON_MISSING_DATA_OPTION 5 + +/** + * This is use to set or get the option value for ICU_TRACE. + * ICU tracing level, is set by command line option. + * Use with set/getTestOption(). + * + * @internal + */ +#define ICU_TRACE_OPTION 6 + +/** + * This is used to set or get the option value for WRITE_GOLDEN_DATA. + * Set to 1 to overwrite golden data files, such as those in testdata/ucptrie. + * Use with set/getTestOption(). + */ +#define WRITE_GOLDEN_DATA_OPTION 7 + +/** + * Maximum amount of memory uprv_malloc should allocate before returning NULL. + * + * @internal + */ +extern T_CTEST_EXPORT_API size_t MAX_MEMORY_ALLOCATION; + +/** + * If memory tracing was enabled, contains the number of unfreed allocations. + * + * @internal + */ +extern T_CTEST_EXPORT_API int32_t ALLOCATION_COUNT; + +/** + * Pass to setTestOption to decrement the test option value. + * + * @internal + */ +#define DECREMENT_OPTION_VALUE -99 + +/** + * Gets the test option set on commandline. + * + * @param testOption macro definition for the individual test option + * @return value of test option, zero if option is not set or off + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API int32_t T_CTEST_EXPORT2 +getTestOption ( int32_t testOption ); + +/** + * Sets the test option with value given on commandline. + * + * @param testOption macro definition for the individual test option + * @param value to set the test option to + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +setTestOption ( int32_t testOption, int32_t value); + +/** + * Show the names of all nodes. + * + * @param root Subtree of tests. + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +showTests ( const TestNode *root); + +/** + * Run a subtree of tests. + * + * @param root Subtree of tests. + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +runTests ( const TestNode* root); + +/** + * Add a test to the subtree. + * Example usage: + * <PRE> + * TestNode* root=NULL; + * addTest(&root, &mytest, "/a/b/mytest" ); + * </PRE> + * @param root Pointer to the root pointer. + * @param test Pointer to 'void function(void)' for actual test. + * @param path Path from root under which test will be placed. Ex. '/a/b/mytest' + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +addTest(TestNode** root, + TestFunctionPtr test, + const char *path); + +/** + * Clean up any allocated memory. + * Conditions for calling this function are the same as u_cleanup(). + * @see u_cleanup + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +cleanUpTestTree(TestNode *tn); + +/** + * Retrieve a specific subtest. (subtree). + * + * @param root Pointer to the root. + * @param path Path relative to the root, Ex. '/a/b' + * @return The subtest, or NULL on failure. + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API const TestNode* T_CTEST_EXPORT2 +getTest(const TestNode* root, + const char *path); + + +/** + * Log an error message. (printf style) + * @param pattern printf-style format string + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +log_err(const char* pattern, ...); + +T_CTEST_API void T_CTEST_EXPORT2 +log_err_status(UErrorCode status, const char* pattern, ...); +/** + * Log an informational message. (printf style) + * @param pattern printf-style format string + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +log_info(const char* pattern, ...); + +/** + * Log an informational message. (vprintf style) + * @param prefix a string that is output before the pattern and without formatting + * @param pattern printf-style format string + * @param ap variable-arguments list + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +vlog_info(const char *prefix, const char *pattern, va_list ap); + +/** + * Log a verbose informational message. (printf style) + * This message will only appear if the global VERBOSITY is nonzero + * @param pattern printf-style format string + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +log_verbose(const char* pattern, ...); + +/** + * Log an error message concerning missing data. (printf style) + * If WARN_ON_MISSING_DATA is nonzero, this will case a log_info (warning) to be + * printed, but if it is zero this will produce an error (log_err). + * @param pattern printf-style format string + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API void T_CTEST_EXPORT2 +log_data_err(const char *pattern, ...); + +/** + * Log a known issue. + * @param ticket ticket number such as "ICU-12345" for ICU tickets or "CLDR-6636" for CLDR tickets. + * @param fmt ... sprintf-style format, optional message. can be NULL. + * @return true if known issue test should be skipped, false if it should be run + */ +T_CTEST_API UBool +T_CTEST_EXPORT2 +log_knownIssue(const char *ticket, const char *fmt, ...); + +/** + * Initialize the variables above. This allows the test to set up accordingly + * before running the tests. + * This must be called before runTests. + */ +T_CTEST_API int T_CTEST_EXPORT2 +initArgs( int argc, const char* const argv[], ArgHandlerPtr argHandler, void *context); + +/** + * Processes the command line arguments. + * This is a sample implementation + * <PRE>Usage: %s [ -l ] [ -v ] [ -? ] [ /path/to/test ] + * -l List only, do not run\ + * -v turn OFF verbosity + * -? print this message</PRE> + * @param root Testnode root with tests already attached to it + * @param argv argument list from main (stdio.h) + * @param argc argument list count from main (stdio.h) + * @return positive for error count, 0 for success, negative for illegal argument + * @internal Internal APIs for testing purpose only + */ +T_CTEST_API int T_CTEST_EXPORT2 +runTestRequest(const TestNode* root, + int argc, + const char* const argv[]); + + +T_CTEST_API const char* T_CTEST_EXPORT2 +getTestName(void); + +/** + * Append a time delta to str if it is significant (>5 ms) otherwise no change + * @param delta a delta in millis + * @param str a string to append to. + */ +T_CTEST_API void T_CTEST_EXPORT2 +str_timeDelta(char *str, UDate delta); + + +/* ======== XML (JUnit output) ========= */ + +/** + * Set the filename for the XML output. + * @param fileName file name. Caller must retain storage. + * @return 0 on success, 1 on failure. + */ +T_CTEST_API int32_t T_CTEST_EXPORT2 +ctest_xml_setFileName(const char *fileName); + + +/** + * Init XML subsystem. Call ctest_xml_setFileName first + * @param rootName the test root name to be written + * @return 0 on success, 1 on failure. + */ +T_CTEST_API int32_t T_CTEST_EXPORT2 +ctest_xml_init(const char *rootName); + + +/** + * Set the filename for the XML output. Caller must retain storage. + * @return 0 on success, 1 on failure. + */ +T_CTEST_API int32_t T_CTEST_EXPORT2 +ctest_xml_fini(void); + + +/** + * report a test case + * @return 0 on success, 1 on failure. + */ +T_CTEST_API int32_t +T_CTEST_EXPORT2 +ctest_xml_testcase(const char *classname, const char *name, const char *time, const char *failMsg); + +#endif diff --git a/intl/icu/source/tools/ctestfw/unicode/datamap.h b/intl/icu/source/tools/ctestfw/unicode/datamap.h new file mode 100644 index 0000000000..b4f7f82fd6 --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/datamap.h @@ -0,0 +1,140 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2006, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +#ifndef U_TESTFW_DATAMAP +#define U_TESTFW_DATAMAP + +#include "unicode/resbund.h" +#include "unicode/testtype.h" + + + +U_NAMESPACE_BEGIN +class Hashtable; +U_NAMESPACE_END + +/** Holder of test data and settings. Allows addressing of items by name. + * For test cases, names are defined in the "Headers" section. For settings + * and info data, names are keys in data. Currently, we return scalar strings + * and integers and arrays of strings and integers. Arrays should be deposited + * of by the user. + */ +class T_CTEST_EXPORT_API DataMap { +public: + virtual ~DataMap(); + +protected: + DataMap(); + int32_t utoi(const UnicodeString &s) const; + + +public: + /** get the string from the DataMap. Addressed by name + * @param key name of the data field. + * @return a string containing the data + */ + virtual const UnicodeString getString(const char* key, UErrorCode &status) const = 0; + + /** get the string from the DataMap. Addressed by name + * parses a bundle string into an integer + * @param key name of the data field. + * @return an integer containing the data + */ + virtual int32_t getInt(const char* key, UErrorCode &status) const = 0; + + /** + * Get a signed integer without runtime parsing. + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer + */ + virtual int32_t getInt28(const char* key, UErrorCode &status) const = 0; + + /** + * Get an unsigned integer without runtime parsing. + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer + */ + virtual uint32_t getUInt28(const char* key, UErrorCode &status) const = 0; + + /** + * Get a vector of integers without runtime parsing. + * @param length output parameter for the length of the vector + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer vector, do not delete + */ + virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const = 0; + + /** + * Get binary data without runtime parsing. + * @param length output parameter for the length of the data + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the binary data, do not delete + */ + virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const = 0; + + /** get an array of strings from the DataMap. Addressed by name. + * The user must dispose of it after usage, using delete. + * @param key name of the data field. + * @return a string array containing the data + */ + virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const = 0; + + /** get an array of integers from the DataMap. Addressed by name. + * The user must dispose of it after usage, using delete. + * @param key name of the data field. + * @return an integer array containing the data + */ + virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const = 0; + + // ... etc ... +}; + +// This one is already concrete - it is going to be instantiated from +// concrete data by TestData children... +class T_CTEST_EXPORT_API RBDataMap : public DataMap{ +private: + Hashtable *fData; + +public: + virtual ~RBDataMap(); + +public: + RBDataMap(); + + RBDataMap(UResourceBundle *data, UErrorCode &status); + RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status); + +public: + void init(UResourceBundle *data, UErrorCode &status); + void init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status); + + virtual const ResourceBundle *getItem(const char* key, UErrorCode &status) const; + + virtual const UnicodeString getString(const char* key, UErrorCode &status) const override; + virtual int32_t getInt28(const char* key, UErrorCode &status) const override; + virtual uint32_t getUInt28(const char* key, UErrorCode &status) const override; + virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const override; + virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const override; + + virtual int32_t getInt(const char* key, UErrorCode &status) const override; + + virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const override; + virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const override; + + // ... etc ... +}; + + +#endif + diff --git a/intl/icu/source/tools/ctestfw/unicode/testdata.h b/intl/icu/source/tools/ctestfw/unicode/testdata.h new file mode 100644 index 0000000000..77db9ceaf1 --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/testdata.h @@ -0,0 +1,113 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2006, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTDATA +#define U_TESTFW_TESTDATA + +#include "unicode/tstdtmod.h" +#include "unicode/datamap.h" + + + /** This is the class that abstracts one of the tests in a data file + * It is usually instantiated using TestDataModule::CreateTestData method + * This class provides two important methods: nextSettings and nextCase + * Usually, one walks through all settings and executes all cases for + * each setting. Each call to nextSettings resets the cases iterator. + * Individual test cases have to have the same number of fields as the + * number of entries in headers. Default headers can be specified in + * the TestDataModule info section. The default headers will be overridden + * by per-test headers. + * Example: + * DataMap *settings = nullptr; + * DataMap *cases = nullptr; + * while(nextSettings(settings, status)) { + * // set settings for the subtest + * while(nextCase(cases, status) { + * // process testcase + * } + * } + */ + +class T_CTEST_EXPORT_API TestData { + const char* name; + +protected: + DataMap *fInfo; + DataMap *fCurrSettings; + DataMap *fCurrCase; + int32_t fSettingsSize; + int32_t fCasesSize; + int32_t fCurrentSettings; + int32_t fCurrentCase; + /** constructor - don't use */ + TestData(const char* name); + +public: + virtual ~TestData(); + + const char* getName() const; + + /** Get a pointer to an object owned DataMap that contains more information on this + * TestData object. + * Usual fields is "Description". + * @param info pass in a const DataMap pointer. If no info, it will be set to nullptr + */ + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0; + + /** Gets the next set of settings for the test. Resets the cases iterator. + * DataMap is owned by the object and should not be deleted. + * @param settings a DataMap pointer provided by the user. Will be nullptr if + * no more settings are available. + * @param status for reporting unexpected errors. + * @return A boolean, true if there are settings, false if there is no more + * settings. + */ + virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status) = 0; + + /** Gets the next test case. + * DataMap is owned by the object and should not be deleted. + * @param data a DataMap pointer provided by the user. Will be nullptr if + * no more cases are available. + * @param status for reporting unexpected errors. + * @return A boolean, true if there are cases, false if there is no more + * cases. + */ + virtual UBool nextCase(const DataMap *& data, UErrorCode &status) = 0; +}; + +// implementation of TestData that uses resource bundles + +class T_CTEST_EXPORT_API RBTestData : public TestData { + UResourceBundle *fData; + UResourceBundle *fHeaders; + UResourceBundle *fSettings; + UResourceBundle *fCases; + +public: + RBTestData(const char* name); + RBTestData(UResourceBundle *data, UResourceBundle *headers, UErrorCode& status); +private: +// RBTestData() {}; +// RBTestData(const RBTestData& original) {}; + RBTestData& operator=(const RBTestData& /*original*/); + +public: + virtual ~RBTestData(); + + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const override; + + virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status) override; + virtual UBool nextCase(const DataMap *& nextCase, UErrorCode &status) override; +}; + +#endif + diff --git a/intl/icu/source/tools/ctestfw/unicode/testlog.h b/intl/icu/source/tools/ctestfw/unicode/testlog.h new file mode 100644 index 0000000000..a7ffbc6084 --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/testlog.h @@ -0,0 +1,62 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2004-2010, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by grhoten 03/17/2004 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTLOG +#define U_TESTFW_TESTLOG + +#include "unicode/errorcode.h" +#include "unicode/unistr.h" +#include "unicode/testtype.h" + +/** Facilitates internal logging of data driven test service + * It would be interesting to develop this into a full + * fledged control system as in Java. + */ +class T_CTEST_EXPORT_API TestLog { +public: + virtual ~TestLog(); + virtual void errln( const UnicodeString &message ) = 0; + virtual void logln( const UnicodeString &message ) = 0; + virtual void dataerrln( const UnicodeString &message ) = 0; + virtual const char* getTestDataPath(UErrorCode& err) = 0; +}; + +class T_CTEST_EXPORT_API IcuTestErrorCode : public ErrorCode { +public: + IcuTestErrorCode(TestLog &callingTestClass, const char *callingTestName) + : testClass(callingTestClass), testName(callingTestName), scopeMessage() {} + virtual ~IcuTestErrorCode(); + + // Returns true if isFailure(). + UBool errIfFailureAndReset(); + UBool errIfFailureAndReset(const char *fmt, ...); + UBool errDataIfFailureAndReset(); + UBool errDataIfFailureAndReset(const char *fmt, ...); + UBool expectErrorAndReset(UErrorCode expectedError); + UBool expectErrorAndReset(UErrorCode expectedError, const char *fmt, ...); + + /** Sets an additional message string to be appended to failure output. */ + void setScope(const char* message); + void setScope(const UnicodeString& message); + +protected: + virtual void handleFailure() const override; + +private: + TestLog &testClass; + const char *const testName; + UnicodeString scopeMessage; + + void errlog(UBool dataErr, const UnicodeString& mainMessage, const char* extraMessage) const; +}; + +#endif diff --git a/intl/icu/source/tools/ctestfw/unicode/testtype.h b/intl/icu/source/tools/ctestfw/unicode/testtype.h new file mode 100644 index 0000000000..a5c70d577a --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/testtype.h @@ -0,0 +1,40 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ***************************************************************************************** + * Copyright (C) 2004-2011, International Business Machines + * Corporation and others. All Rights Reserved. + ***************************************************************************************** + */ + +#include "unicode/utypes.h" + +/*Deals with imports and exports of the dynamic library*/ +#if !defined(U_STATIC_IMPLEMENTATION) + #define T_CTEST_EXPORT U_EXPORT + #define T_CTEST_IMPORT U_IMPORT +#else + #define T_CTEST_EXPORT + #define T_CTEST_IMPORT +#endif + +#if defined(_MSC_VER) +#define T_CTEST_EXPORT2 __cdecl +#else +#define T_CTEST_EXPORT2 +#endif + +#ifdef __cplusplus + #define C_CTEST_API extern "C" + U_NAMESPACE_USE +#else + #define C_CTEST_API +#endif + +#ifdef T_CTEST_IMPLEMENTATION + #define T_CTEST_API C_CTEST_API T_CTEST_EXPORT + #define T_CTEST_EXPORT_API T_CTEST_EXPORT +#else + #define T_CTEST_API C_CTEST_API T_CTEST_IMPORT + #define T_CTEST_EXPORT_API T_CTEST_IMPORT +#endif diff --git a/intl/icu/source/tools/ctestfw/unicode/tstdtmod.h b/intl/icu/source/tools/ctestfw/unicode/tstdtmod.h new file mode 100644 index 0000000000..fb2f19631d --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/tstdtmod.h @@ -0,0 +1,117 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2005, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTMODULE +#define U_TESTFW_TESTMODULE + +#include "unicode/unistr.h" +#include "unicode/ures.h" +#include "unicode/testtype.h" +#include "unicode/testdata.h" +#include "unicode/datamap.h" +#include "unicode/testlog.h" + + +/* This class abstracts the actual organization of the + * data for data driven tests + */ + + +class DataMap; +class TestData; + + +/** Main data driven test class. Corresponds to one named data + * unit (such as a resource bundle. It is instantiated using + * a factory method getTestDataModule + */ +class T_CTEST_EXPORT_API TestDataModule { + const char* testName; + +protected: + DataMap *fInfo; + TestLog& fLog; + +public: + /** Factory method. + * @param name name of the test module. Usually name of a resource bundle or a XML file + * @param log a logging class, used for internal error reporting. + * @param status if something goes wrong, status will be set + * @return a TestDataModule object. Use it to get test data from it + */ + static TestDataModule *getTestDataModule(const char* name, TestLog& log, UErrorCode &status); + virtual ~TestDataModule(); + +protected: + TestDataModule(const char* name, TestLog& log, UErrorCode& status); + +public: + /** Name of this TestData module. + * @return a name + */ + const char * getName() const; + + /** Get a pointer to an object owned DataMap that contains more information on this module + * Usual fields are "Description", "LongDescription", "Settings". Also, if containing a + * field "Headers" these will be used as the default headers, so that you don't have to + * to specify per test headers. + * @param info pass in a const DataMap pointer. If no info, it will be set to nullptr + */ + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0; + + /** Create a test data object from an index. Helpful for integrating tests with current + * intltest framework which addresses the tests by index. + * @param index index of the test to be instantiated + * @return an instantiated TestData object, ready to provide settings and cases for + * the tests. + */ + virtual TestData* createTestData(int32_t index, UErrorCode &status) const = 0; + + /** Create a test data object from a name. + * @param name name of the test to be instantiated + * @return an instantiated TestData object, ready to provide settings and cases for + * the tests. + */ + virtual TestData* createTestData(const char* name, UErrorCode &status) const = 0; +}; + +class T_CTEST_EXPORT_API RBTestDataModule : public TestDataModule { +public: + virtual ~RBTestDataModule(); + +public: + RBTestDataModule(const char* name, TestLog& log, UErrorCode& status); + +public: + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const override; + + virtual TestData* createTestData(int32_t index, UErrorCode &status) const override; + virtual TestData* createTestData(const char* name, UErrorCode &status) const override; + +private: + UResourceBundle *getTestBundle(const char* bundleName, UErrorCode &status); + +private: + UResourceBundle *fModuleBundle; + UResourceBundle *fTestData; + UResourceBundle *fInfoRB; + UBool fDataTestValid; + char *tdpath; + +/* const char* fTestName;*/ /* See name */ + int32_t fNumberOfTests; + +}; + + +#endif + diff --git a/intl/icu/source/tools/ctestfw/unicode/uperf.h b/intl/icu/source/tools/ctestfw/unicode/uperf.h new file mode 100644 index 0000000000..e578c46694 --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/uperf.h @@ -0,0 +1,200 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +********************************************************************** +* Copyright (c) 2002-2014, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +*/ +#ifndef _UPERF_H +#define _UPERF_H + +#include "unicode/utypes.h" +#include "unicode/unistr.h" +#include "unicode/ustring.h" + +#include "unicode/testtype.h" +#include "unicode/utimer.h" +#include "ucbuf.h" + +// Forward declarations from uoptions.h. +struct UOption; +typedef struct UOption UOption; + +#if !UCONFIG_NO_CONVERSION + +U_NAMESPACE_USE +// Use the TESTCASE macro in subclasses of UPerfTest. Define the +// runIndexedTest method in this fashion: +// +//| void MyTest::runIndexedTest(int32_t index, UBool exec, +//| const char* &name, char* /*par*/) { +//| switch (index) { +//| TESTCASE(0,TestSomething); +//| TESTCASE(1,TestSomethingElse); +//| TESTCASE(2,TestAnotherThing); +//| default: +//| name = ""; +//| break; +//| } +//| return nullptr; +//| } +#define TESTCASE(id,test) \ + case id: \ + name = #test; \ + if (exec) { \ + return test(); \ + } \ + break + +// More convenient macros. These allow easy reordering of the test cases. +// Copied from intltest.h, and adjusted to not logln() but return a UPerfFunction. +// +//| void MyTest::runIndexedTest(int32_t index, UBool exec, +//| const char* &name, char* /*par*/) { +//| TESTCASE_AUTO_BEGIN; +//| TESTCASE_AUTO(TestSomething); +//| TESTCASE_AUTO(TestSomethingElse); +//| TESTCASE_AUTO(TestAnotherThing); +//| TESTCASE_AUTO_END; +//| return nullptr; +//| } +#define TESTCASE_AUTO_BEGIN \ + for(;;) { \ + int32_t testCaseAutoNumber = 0 + +#define TESTCASE_AUTO(test) \ + if (index == testCaseAutoNumber++) { \ + name = #test; \ + if (exec) { \ + return test(); \ + } \ + break; \ + } + +#define TESTCASE_AUTO_END \ + name = ""; \ + break; \ + } + +/** + * Subclasses of PerfTest will need to create subclasses of + * Function that define a call() method which contains the code to + * be timed. They then call setTestFunction() in their "Test..." + * method to establish this as the current test functor. + */ +class T_CTEST_EXPORT_API UPerfFunction { +public: + /** + * destructor + */ + virtual ~UPerfFunction(); + + /** + * Subclasses must implement this method to do the action to be + * measured. + */ + virtual void call(UErrorCode* status)=0; + + /** + * Subclasses must implement this method to return positive + * integer indicating the number of operations in a single + * call to this object's call() method. + */ + virtual long getOperationsPerIteration()=0; + /** + * Subclasses should override this method to return either positive + * or negative integer indicating the number of events in a single + * call to this object's call() method, if applicable + * e.g: Number of breaks / iterations for break iterator + */ + virtual long getEventsPerIteration(){ + return -1; + } + /** + * Call call() n times in a tight loop and return the elapsed + * milliseconds. If n is small and call() is fast the return + * result may be zero. Small return values have limited + * meaningfulness, depending on the underlying CPU and OS. + */ + virtual double time(int32_t n, UErrorCode* status) { + UTimer start, stop; + utimer_getTime(&start); + while (n-- > 0) { + call(status); + } + utimer_getTime(&stop); + return utimer_getDeltaSeconds(&start,&stop); // ms + } + +}; + + +class T_CTEST_EXPORT_API UPerfTest { +public: + UBool run(); + UBool runTest( char* name = nullptr, char* par = nullptr ); // not to be overridden + + virtual void usage() ; + + virtual ~UPerfTest(); + + void setCaller( UPerfTest* callingTest ); // for internal use only + + void setPath( char* path ); // for internal use only + + ULine* getLines(UErrorCode& status); + + const char16_t* getBuffer(int32_t& len,UErrorCode& status); + +protected: + UPerfTest(int32_t argc, const char* argv[], UErrorCode& status); + + UPerfTest(int32_t argc, const char* argv[], + UOption addOptions[], int32_t addOptionsCount, + const char *addUsage, + UErrorCode& status); + + void init(UOption addOptions[], int32_t addOptionsCount, + UErrorCode& status); + + virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = nullptr ); // override ! + + virtual UBool runTestLoop( char* testname, char* par ); + + virtual UBool callTest( UPerfTest& testToBeCalled, char* par ); + + int32_t _argc; + const char** _argv; + const char * _addUsage; + char* resolvedFileName; + UCHARBUF* ucharBuf; + const char* encoding; + UBool uselen; + const char* fileName; + const char* sourceDir; + int32_t _remainingArgc; + ULine* lines; + int32_t numLines; + UBool line_mode; + char16_t* buffer; + int32_t bufferLen; + UBool verbose; + UBool bulk_mode; + int32_t passes; + int32_t iterations; + int32_t time; + const char* locale; +private: + UPerfTest* caller; + char* path; // specifies subtests + +// static members +public: + static UPerfTest* gTest; + static const char gUsageString[]; +}; + +#endif +#endif + diff --git a/intl/icu/source/tools/ctestfw/unicode/utimer.h b/intl/icu/source/tools/ctestfw/unicode/utimer.h new file mode 100644 index 0000000000..10f80833cb --- /dev/null +++ b/intl/icu/source/tools/ctestfw/unicode/utimer.h @@ -0,0 +1,282 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +************************************************************************ +* Copyright (c) 1997-2012, International Business Machines +* Corporation and others. All Rights Reserved. +************************************************************************ +*/ + +#ifndef _UTIMER_H +#define _UTIMER_H + +#include "unicode/utypes.h" + +#if U_PLATFORM_USES_ONLY_WIN32_API +# define VC_EXTRALEAN +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#else +# if U_PLATFORM == U_PF_OS390 && !defined(__UU) +# define __UU /* Universal Unix - for struct timeval */ +# endif +# include <time.h> +# include <sys/time.h> +# include <unistd.h> +#endif + +/** + * This API provides functions for performing performance measurement + * There are 3 main usage scenarios. + * i) Loop until a threshold time is reached: + * Example: + * <code> + * typedef Params Params; + * struct Params{ + * char16_t* target; + * int32_t targetLen; + * const char16_t* source; + * int32_t sourceLen; + * UNormalizationMode mode; + * } + * void NormFn( void* param){ + * Params* parameters = ( Params*) param; + * UErrorCode error = U_ZERO_ERROR; + * unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error); + * if(U_FAILURE(error)){ + * printf("Normalization failed\n"); + * } + * } + * + * int main(){ + * // time the normalization function + * double timeTaken = 0; + * Params param; + * param.source // set up the source buffer + * param.target // set up the target buffer + * .... so on ... + * UTimer timer; + * // time the loop for 10 seconds at least and find out the loop count and time taken + * timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount); + * } + * </code> + * + * ii) Measure the time taken + * Example: + * <code> + * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){ + * int line; + * int loops; + * UErrorCode error = U_ZERO_ERROR; + * char16_t* dest=nullptr; + * int32_t destCapacity=0; + * int len =-1; + * double elapsedTime = 0; + * int retVal=0; + * + * char16_t arr[5000]; + * dest=arr; + * destCapacity = 5000; + * UTimer start; + * + * // Initialize cache and ensure the data is loaded. + * // This loop checks for errors in Normalization. Once we pass the initialization + * // without errors we can safelly assume that there are no errors while timing the + * // function + * for (loops=0; loops<10; loops++) { + * for (line=0; line < gNumFileLines; line++) { + * if (opt_uselen) { + * len = fileLines[line].len; + * } + * + * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error); + * #if U_PLATFORM_HAS_WIN32_API + * if(retVal==0 ){ + * fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line); + * return 0; + * } + * #endif + * if(U_FAILURE(error)){ + * fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line); + * return 0; + * } + * + * } + * } + * + * //compute the time + * + * utimer_getTime(&start); + * for (loops=0; loops<loopCount; loops++) { + * for (line=0; line < gNumFileLines; line++) { + * if (opt_uselen) { + * len = fileLines[line].len; + * } + * + * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error); + * + * } + * } + * + * return utimer_getElapsedSeconds(&start); + * } + * </code> + * + * iii) Let a higher level function do the calculation of confidence levels etc. + * Example: + * <code> + * void perf(UTimer* timer, char16_t* source, int32_t sourceLen, char16_t* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){ + * int32_t loops; + * for (loops=0; loops<loopCount; loops++) { + * unorm_normalize(source,sourceLen,target, targetLen,mode,error); + * } + * utimer_getTime(timer); + * } + * void main(const char* argsc, int argv){ + * // read the file and setup the data + * // set up options + * UTimer start,timer1, timer2, timer3, timer4; + * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken; + * switch(opt){ + * case 0: + * utimer_getTime(start); + * perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error); + * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1); + * case 1: + * timer_getTime(start); + * perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error); + * NFCTimeTaken = utimer_getDeltaSeconds(start,timer2); + * perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error); + * // ........so on ............. + * } + * // calculate confidence levels etc and print + * + * } + * + * </code> + * + */ + +typedef struct UTimer UTimer; + +typedef void FunctionToBeTimed(void* param); + + +#if U_PLATFORM_USES_ONLY_WIN32_API + + struct UTimer{ + LARGE_INTEGER start; + LARGE_INTEGER placeHolder; + }; + +static int uprv_initFrequency(UTimer* timer) + { + return QueryPerformanceFrequency(&timer->placeHolder); + } +static void uprv_start(UTimer* timer) + { + QueryPerformanceCounter(&timer->start); + } +static double uprv_delta(UTimer* timer1, UTimer* timer2){ + return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart); + } +static UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){ + return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart); + } + +#else + + struct UTimer{ + struct timeval start; + struct timeval placeHolder; + }; + +static int32_t uprv_initFrequency(UTimer* /*timer*/) + { + return 0; + } +static void uprv_start(UTimer* timer) + { + gettimeofday(&timer->start, 0); + } +static double uprv_delta(UTimer* timer1, UTimer* timer2){ + double t1, t2; + + t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000); + t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000); + return (t2-t1); + } +static UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){ + return true; + } + +#endif +/** + * Initializes the timer with the current time + * + * @param timer A pointer to UTimer struct to receive the current time + */ +static inline void U_EXPORT2 +utimer_getTime(UTimer* timer){ + uprv_initFrequency(timer); + uprv_start(timer); +} + +/** + * Returns the difference in times between timer1 and timer2 by subtracting + * timer1's time from timer2's time + * + * @param timer1 A pointer to UTimer struct to be used as starting time + * @param timer2 A pointer to UTimer struct to be used as end time + * @return Time in seconds + */ +static inline double U_EXPORT2 +utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){ + if(uprv_compareFrequency(timer1,timer2)){ + return uprv_delta(timer1,timer2); + } + /* got error return -1 */ + return -1; +} + +/** + * Returns the time elapsed from the starting time represented by the + * UTimer struct pointer passed + * @param timer A pointer to UTimer struct to be used as starting time + * @return Time elapsed in seconds + */ +static inline double U_EXPORT2 +utimer_getElapsedSeconds(UTimer* timer){ + UTimer temp; + utimer_getTime(&temp); + return uprv_delta(timer,&temp); +} + +/** + * Executes the function pointed to for a given time and returns exact time + * taken and number of iterations of the loop + * @param thresholTimeVal + * @param loopCount output param to receive the number of iterations + * @param fn The function to be executed + * @param param Parameters to be passed to the fn + * @return the time elapsed in seconds + */ +static inline double U_EXPORT2 +utimer_loopUntilDone(double thresholdTimeVal, + int32_t* loopCount, + FunctionToBeTimed fn, + void* param){ + UTimer timer; + double currentVal=0; + *loopCount = 0; + utimer_getTime(&timer); + for(;currentVal<thresholdTimeVal;){ + fn(param); + currentVal = utimer_getElapsedSeconds(&timer); + (*loopCount)++; + } + return currentVal; +} + +#endif + |