You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2007/10/03 06:25:39 UTC
svn commit: r581488 -
/logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp
Author: carnold
Date: Tue Oct 2 21:25:39 2007
New Revision: 581488
URL: http://svn.apache.org/viewvc?rev=581488&view=rev
Log:
LOGCXX-175: APRCharsetEncoder threading test
Modified:
logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp
Modified: logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp?rev=581488&r1=581487&r2=581488&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp Tue Oct 2 21:25:39 2007
@@ -21,16 +21,22 @@
#include <log4cxx/helpers/charsetencoder.h>
#include "../insertwide.h"
#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/thread.h>
+#include <log4cxx/helpers/mutex.h>
+#include <log4cxx/helpers/condition.h>
+#include <log4cxx/helpers/synchronized.h>
+#include <apr.h>
+#include <apr_atomic.h>
+
using namespace log4cxx;
using namespace log4cxx::helpers;
-#define APR_SUCCESS ((log4cxx_status_t) 0)
-
class CharsetEncoderTestCase : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(CharsetEncoderTestCase);
+ CPPUNIT_TEST(thread1);
CPPUNIT_TEST(encode1);
CPPUNIT_TEST(encode2);
CPPUNIT_TEST(encode3);
@@ -165,7 +171,128 @@
}
CPPUNIT_ASSERT(iter == greeting.end());
}
+
+ class ThreadPackage {
+ public:
+ ThreadPackage(CharsetEncoderPtr& enc, int repetitions) :
+ p(), lock(p), condition(p), passCount(0), failCount(0), enc(enc), repetitions(repetitions) {
+ }
+
+ void await() {
+ synchronized sync(lock);
+ condition.await(lock);
+ }
+
+ void signalAll() {
+ synchronized sync(lock);
+ condition.signalAll();
+ }
+
+ void fail() {
+ apr_atomic_inc32(&failCount);
+ }
+
+ void pass() {
+ apr_atomic_inc32(&passCount);
+ }
+
+ apr_uint32_t getFail() {
+ return apr_atomic_read32(&failCount);
+ }
+
+ apr_uint32_t getPass() {
+ return apr_atomic_read32(&passCount);
+ }
+
+ int getRepetitions() {
+ return repetitions;
+ }
+
+ CharsetEncoderPtr& getEncoder() {
+ return enc;
+ }
+
+ private:
+ ThreadPackage(const ThreadPackage&);
+ ThreadPackage& operator=(ThreadPackage&);
+ Pool p;
+ Mutex lock;
+ Condition condition;
+ volatile apr_uint32_t passCount;
+ volatile apr_uint32_t failCount;
+ CharsetEncoderPtr enc;
+ int repetitions;
+ };
+
+ static void* LOG4CXX_THREAD_FUNC thread1Action(log4cxx_thread_t* thread, void* data) {
+ ThreadPackage* package = (ThreadPackage*) data;
+ const char utf8_greet[] = { 'A',
+ (char) 0xD8, (char) 0x85,
+ (char) 0xD4, (char) 0xB0,
+ (char) 0xE0, (char) 0xA6, (char) 0x86,
+ (char) 0xE4, (char) 0xB8, (char) 0x83,
+ (char) 0xD0, (char) 0x80,
+ 0 };
+#if LOG4CXX_LOGCHAR_IS_WCHAR
+ // arbitrary, hopefully meaningless, characters from
+ // Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
+ const logchar greet[] = { L'A', 0x0605, 0x0530, 0x986, 0x4E03, 0x400, 0 };
+#endif
+
+#if LOG4CXX_LOGCHAR_IS_UTF8
+ const logchar *greet = utf8_greet;
+#endif
+ LogString greeting(greet);
+
+ package->await();
+ for(int i = 0; i < package->getRepetitions(); i++) {
+ bool pass = true;
+ char buf[BUFSIZE];
+ ByteBuffer out(buf, BUFSIZE);
+ LogString::const_iterator iter = greeting.begin();
+ log4cxx_status_t stat = package->getEncoder()->encode(greeting, iter, out);
+ pass = (false == CharsetEncoder::isError(stat));
+ if (pass) {
+ stat = package->getEncoder()->encode(greeting, iter, out);
+ pass = (false == CharsetEncoder::isError(stat));
+ if (pass) {
+ out.flip();
+ pass = (13 == out.limit());
+ for(size_t i = 0; i < out.limit() && pass; i++) {
+ pass = (utf8_greet[i] == out.data()[i]);
+ }
+ pass = pass && (iter == greeting.end());
+ }
+ }
+ if (pass) {
+ package->pass();
+ } else {
+ package->fail();
+ }
+ }
+ return 0;
+ }
+ void thread1() {
+ enum { THREAD_COUNT = 10, THREAD_REPS = 10000 };
+ Thread threads[THREAD_COUNT];
+ CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("ISO-8859-1")));
+ ThreadPackage* package = new ThreadPackage(enc, THREAD_REPS);
+ for(int i = 0; i < THREAD_COUNT; i++) {
+ threads[i].run(thread1Action, package);
+ }
+ //
+ // give time for all threads to be launched so
+ // we don't signal before everybody is waiting.
+ Thread::sleep(100);
+ package->signalAll();
+ for(int i = 0; i < THREAD_COUNT; i++) {
+ threads[i].join();
+ }
+ CPPUNIT_ASSERT_EQUAL((apr_uint32_t) 0, package->getFail());
+ CPPUNIT_ASSERT_EQUAL((apr_uint32_t) THREAD_COUNT * THREAD_REPS, package->getPass());
+ delete package;
+ }
};