test harness for windows shib-threads.cpp, could work on unix without too much troubl...
authorAaron Wohl <xshib@awohl.com>
Tue, 20 May 2003 19:48:03 +0000 (19:48 +0000)
committerAaron Wohl <xshib@awohl.com>
Tue, 20 May 2003 19:48:03 +0000 (19:48 +0000)
does not at this time

shib/shibthreadswin32test/ReadMe.txt [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.cpp [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.dsp [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.dsw [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.ncb [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.opt [new file with mode: 0644]
shib/shibthreadswin32test/shibthreadswin32test.plg [new file with mode: 0644]
shib/shibthreadswin32test/stdafx.cpp [new file with mode: 0644]
shib/shibthreadswin32test/stdafx.h [new file with mode: 0644]

diff --git a/shib/shibthreadswin32test/ReadMe.txt b/shib/shibthreadswin32test/ReadMe.txt
new file mode 100644 (file)
index 0000000..d8190fd
--- /dev/null
@@ -0,0 +1,5 @@
+shibthreadswin32test.cpp by Aaron Wohl xshib@awohl.com
+
+shibthreadswin32test.cpp tests each of the operations defined in 
+shib-threads.h.  With different #include files it would probably
+work on unix.
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.cpp b/shib/shibthreadswin32test/shibthreadswin32test.cpp
new file mode 100644 (file)
index 0000000..64de514
--- /dev/null
@@ -0,0 +1,292 @@
+// shibthreadswin32test.cpp : by Aaron Wohl xshib@awohl.com.
+//
+
+#ifdef RUBBISH
+CondWait broadcast is not implemented on win32. The semantics are different for
+broadcast like events on win32.  If waking multiple waiters is needed then
+need to think about it.
+   
+CondWait lock realease/wake up/lock get are not atomic on win32.  I dont think
+that matters the way its used.  On wake up CondWait waits for the condition event or timeout.  After wake up it locks the mutex again.  Its not guarenteed that the one process that was signaled is the one that gets the lock next.
+#endif
+
+#include "stdafx.h"
+#include "shib-threads.h"
+#include "windows.h"
+#include <list>
+#include <iostream>
+
+using namespace shibboleth;
+using namespace std;
+
+#define ASSERT(xxx) \
+do { \
+if(!(xxx)) { \
+       fprintf(stderr,"assert failed " #xxx); \
+        do_exit(1); \
+} \
+}while (0)
+
+static volatile int basic_loop_count;
+#define NUM_BASIC_LOOP (100)
+
+static do_exit(int rc)
+{
+  char ch;
+  cout << "press a key to exit" << endl;
+  cout << "exit code is " << rc << " (0 is good)" << endl;
+  cin >> ch;
+  exit(rc);
+}
+
+static void *basic_loop_thread(void *x)
+{
+  for(int i=0;i<NUM_BASIC_LOOP;i++)
+    basic_loop_count++;
+  return 0;
+}
+
+static void test_basic_loop(void)
+{
+  Thread *athr=Thread::create(&basic_loop_thread,0);
+  ASSERT(athr!=0);
+  void *return_val;
+  athr->join(&return_val);
+  ASSERT(basic_loop_count==NUM_BASIC_LOOP);
+}
+
+static RWLock *arwlock;
+
+static int roll(int n)
+{
+  return rand() % n;
+}
+
+static int shared_count;
+#define NUM_READERS (3)
+static volatile bool in_readern[NUM_READERS];
+
+static void check_shared(void)
+{
+  int share_count=0;
+  for(int i=0;i<NUM_READERS;i++)
+    if(in_readern[i])
+      share_count++;
+  ASSERT(share_count>0);
+  ASSERT(share_count<=NUM_READERS);
+  if(share_count>1)
+    shared_count++;
+}
+
+static int num_keys_disposed;
+
+static void key_test_fcn(void *x)
+{
+  num_keys_disposed++;
+}
+
+static void *lock_reader(void *x)
+{
+  int locker_num=int(x);
+  ThreadKey *akey=ThreadKey::create(key_test_fcn);
+  ASSERT(akey!=0);
+  akey->setData(x);
+  for(int i=0;i<NUM_BASIC_LOOP;i++) {
+    ASSERT(arwlock->rdlock()==0);
+    in_readern[locker_num]=true;
+    Sleep(roll(500));
+    // make sure the thread local storage really is thread local
+    // if its not some other reader will trash it
+    ASSERT(akey->getData()==x);
+    check_shared();
+    in_readern[locker_num]=false;
+    ASSERT(arwlock->unlock()==0);
+    Sleep(roll(500));
+  }
+  delete akey;
+  return 0;
+}
+
+static void *lock_writer(void *y)
+{
+ for(int i=0;i<NUM_BASIC_LOOP;i++) {
+  ASSERT(arwlock->wrlock()==0);
+  Sleep(roll(500));
+  ASSERT(arwlock->unlock()==0);
+  Sleep(roll(500));
+  }
+ return 0;
+}
+
+static void test_rwlock()
+{
+ arwlock=RWLock::create();
+ {
+  bool cant_unlock_an_unlocked_lock=(arwlock->unlock()!=0);
+  ASSERT(cant_unlock_an_unlocked_lock);
+ }
+ list<Thread*> tl;
+ for(int i=0;i<NUM_READERS;i++) {
+   Thread *athr=Thread::create(&lock_reader,(void *)i);
+   tl.push_back(athr);
+   ASSERT(athr!=0);
+   Thread *athw=Thread::create(&lock_writer,0);
+   ASSERT(athw!=0);
+   tl.push_back(athw);
+ }
+ while(!tl.empty()) {
+    Thread *some_thread=tl.front();
+    void *return_val;
+    some_thread->join(&return_val);
+    tl.pop_front();
+ }
+ delete arwlock;
+ ASSERT(num_keys_disposed==NUM_READERS);
+}
+
+static void *empty_thread(void *x)
+{
+  return 0;
+}
+
+static void test_detach(void)
+{
+  Thread *ath=Thread::create(empty_thread,0);
+  ASSERT(ath->detach()==0);
+  // cant detch or join after already detach
+  ASSERT(ath->detach()!=0);
+  void *return_val;
+  ASSERT(ath->join(&return_val)!=0);
+  ASSERT(ath->detach()!=0);
+  delete ath;
+}
+
+static int in_kill_proc;
+
+static void *kill_me(void *x)
+{
+  while(1) {
+    in_kill_proc++;
+    Sleep(5);
+  }
+  return 0;
+}
+
+static void test_kill(void)
+{
+  Thread *ath=Thread::create(kill_me,0);
+  while(in_kill_proc<3)
+    Sleep(5);
+
+  ASSERT(ath->kill(23)==0);
+  delete ath;
+}
+
+static void test_detach_kill(void)
+{
+  test_detach();
+  test_kill();
+}
+
+static void test_cond_timeout(void)
+{
+  Mutex *m=Mutex::create();
+  ASSERT(m!=0);
+  CondWait *cw=CondWait::create();  
+  ASSERT(cw!=0);
+  ASSERT(m->lock()==0);
+  time_t start_time=time(0L);
+#define DELAY_TIME (7)
+  ASSERT(cw->timedwait(m,DELAY_TIME)==0);
+  int slept_for=time(0L)-start_time;
+  ASSERT(m->unlock()==0);
+  delete cw;
+  delete m;
+  int delta_time=abs(DELAY_TIME-slept_for);
+  if(delta_time>2)
+    do_exit(1);
+  cout << "CondWait: timed test ok" << endl;
+}
+
+
+static int cond_counter;
+static CondWait *cond_wait;
+
+static void *cond_incrementer(void *x)
+{
+  Mutex *cm=(Mutex *)(x);
+  for(int i=0;i<NUM_BASIC_LOOP;i++) {
+    ASSERT(cm->lock()==0);
+    cond_counter++;
+    if(cond_counter==(NUM_BASIC_LOOP+NUM_BASIC_LOOP/2))
+      ASSERT(cond_wait->signal()==0);
+    ASSERT(cm->lock()==0);
+  }
+  return 0;
+}
+
+static void test_cond_signal(void)
+{
+  Mutex *cm=Mutex::create();
+  ASSERT(cm!=0);
+  ASSERT(cm->lock()==0);
+  cond_wait=CondWait::create();
+  list<Thread*> tl;
+  for(int i=0;i<2;i++) {
+    Thread *athr=Thread::create(&cond_incrementer,(void *)cm);
+    tl.push_back(athr);
+    ASSERT(athr!=0);
+  }
+  ASSERT(cond_wait->wait(cm)==0);
+  ASSERT(cm->unlock()==0);
+  while(!tl.empty()) {
+    Thread *some_thread=tl.front();
+    void *return_val;
+    some_thread->join(&return_val);
+    tl.pop_front();
+  }
+  delete cond_wait;
+  delete cm;
+  cout << "CondWait: signal test ok" << endl;
+}
+
+static void test_cond_wait(void)
+{
+  test_cond_timeout();
+  test_cond_signal();
+}
+
+static void protected_run_tests(void)
+{
+  test_cond_wait();
+  test_detach_kill();
+  test_basic_loop();
+  test_rwlock();
+}
+
+static void run_tests(void)
+{
+       try {
+               protected_run_tests();
+       } catch (char *s) {
+               cout << "caught error" << s << endl;
+               do_exit(1);
+       } catch (...) {
+               cout << "caught unknown error" << endl;
+               do_exit(1);
+       }
+
+}
+
+int main(int argc, char* argv[])
+{
+  cout << "testing shib-threads, will take like 5min, look for an ok at the end\n";
+  run_tests();
+  cout << "tests done\n";
+  cout << "readers shared " << shared_count << " times (0 shares is bad)" << endl;
+  if(shared_count<1)
+    do_exit(1);
+  do_exit(0);
+  return 0;
+}
+
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.dsp b/shib/shibthreadswin32test/shibthreadswin32test.dsp
new file mode 100644 (file)
index 0000000..d26e3a7
--- /dev/null
@@ -0,0 +1,120 @@
+# Microsoft Developer Studio Project File - Name="shibthreadswin32test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=shibthreadswin32test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "shibthreadswin32test.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "shibthreadswin32test.mak" CFG="shibthreadswin32test - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "shibthreadswin32test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "shibthreadswin32test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "shibthreadswin32test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "shibthreadswin32test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ  /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I ".." /I "../.." /I "../../../../opensaml/c" /I "../../../../xerces-c2_2_0-win32/include" /I "../../../../xml-security-0.2.0/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_AFXDLL" /D "STANDALONE_SHIBTHREADS_TESTING" /YX"pre_header" /FD /GZ  /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "shibthreadswin32test - Win32 Release"
+# Name "shibthreadswin32test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\shib-threads-win32.cpp"
+
+!IF  "$(CFG)" == "shibthreadswin32test - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "shibthreadswin32test - Win32 Debug"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\shibthreadswin32test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.dsw b/shib/shibthreadswin32test/shibthreadswin32test.dsw
new file mode 100644 (file)
index 0000000..1d46ecd
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "shibthreadswin32test"=.\shibthreadswin32test.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.ncb b/shib/shibthreadswin32test/shibthreadswin32test.ncb
new file mode 100644 (file)
index 0000000..318489a
Binary files /dev/null and b/shib/shibthreadswin32test/shibthreadswin32test.ncb differ
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.opt b/shib/shibthreadswin32test/shibthreadswin32test.opt
new file mode 100644 (file)
index 0000000..266d613
Binary files /dev/null and b/shib/shibthreadswin32test/shibthreadswin32test.opt differ
diff --git a/shib/shibthreadswin32test/shibthreadswin32test.plg b/shib/shibthreadswin32test/shibthreadswin32test.plg
new file mode 100644 (file)
index 0000000..abe19cc
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: shibthreadswin32test - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\wohl\LOCALS~1\Temp\RSP2BF.tmp" with contents
+[
+/nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I ".." /I "../.." /I "../../../../opensaml/c" /I "../../../../xerces-c2_2_0-win32/include" /I "../../../../xml-security-0.2.0/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_AFXDLL" /D "STANDALONE_SHIBTHREADS_TESTING" /Fp"Debug/shibthreadswin32test.pch" /YX"pre_header" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
+"C:\TEMP\SHIB\MAY.19.SHIB\SHIBBOLETH\C\SHIB\shibthreadswin32test\shibthreadswin32test.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\wohl\LOCALS~1\Temp\RSP2BF.tmp" 
+Creating command line "link.exe /nologo /subsystem:console /incremental:yes /pdb:"Debug/shibthreadswin32test.pdb" /debug /machine:I386 /out:"Debug/shibthreadswin32test.exe" /pdbtype:sept  ".\Debug\shib-threads-win32.obj" .\Debug\shibthreadswin32test.obj .\Debug\StdAfx.obj "
+<h3>Output Window</h3>
+Compiling...
+shibthreadswin32test.cpp
+Linking...
+
+
+
+<h3>Results</h3>
+shibthreadswin32test.exe - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>
diff --git a/shib/shibthreadswin32test/stdafx.cpp b/shib/shibthreadswin32test/stdafx.cpp
new file mode 100644 (file)
index 0000000..89f7d25
--- /dev/null
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+//     shibthreadswin32test.pch will be the pre-compiled header
+//     stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/shib/shibthreadswin32test/stdafx.h b/shib/shibthreadswin32test/stdafx.h
new file mode 100644 (file)
index 0000000..33b83c1
--- /dev/null
@@ -0,0 +1,22 @@
+// stdafx.h : include file for standard system include files,
+//  or project specific include files that are used frequently, but
+//      are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__8671ECDA_FBD6_4D11_B85A_B7E12AC1C646__INCLUDED_)
+#define AFX_STDAFX_H__8671ECDA_FBD6_4D11_B85A_B7E12AC1C646__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define xWIN32_LEAN_AND_MEAN           // Exclude rarely-used stuff from Windows headers
+
+#include <stdio.h>
+
+// TODO: reference additional headers your program requires here
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__8671ECDA_FBD6_4D11_B85A_B7E12AC1C646__INCLUDED_)