summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/tools/ctestfw/unicode
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/ctest.h321
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/datamap.h140
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/testdata.h113
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/testlog.h62
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/testtype.h40
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/tstdtmod.h117
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/uperf.h200
-rw-r--r--intl/icu/source/tools/ctestfw/unicode/utimer.h282
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
+