00001 /*!@file TestSuite/whitebox-Beowulf.C Whitebox tests of Beowulf and 00002 related classes. */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00006 // by the University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/TestSuite/whitebox-Beowulf.C $ 00036 // $Id: whitebox-Beowulf.C 9061 2007-11-29 18:31:14Z rjpeters $ 00037 // 00038 00039 #ifndef TESTSUITE_WHITEBOX_BEOWULF_C_DEFINED 00040 #define TESTSUITE_WHITEBOX_BEOWULF_C_DEFINED 00041 00042 #include "Beowulf/Beowulf.H" 00043 #include "Beowulf/TCPmessage.H" 00044 #include "Component/ModelManager.H" 00045 #include "Image/Image.H" 00046 #include "Image/Pixels.H" 00047 #include "TestSuite/TestSuite.H" 00048 #include "Util/Timer.H" 00049 #include "Util/csignals.H" 00050 00051 #include <limits> 00052 #include <signal.h> // for kill() 00053 #include <sys/types.h> // for pid_t 00054 #include <sys/wait.h> // for waitpid() 00055 #include <unistd.h> 00056 00057 namespace 00058 { 00059 int run_master(TCPmessage* rmsg) 00060 { 00061 try 00062 { 00063 MYLOGPREFIX = "master"; 00064 00065 ModelManager manager("test-master"); 00066 00067 nub::soft_ref<Beowulf> beomaster 00068 (new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true)); 00069 manager.addSubComponent(beomaster); 00070 00071 const char* argv[] = { "test-master", "--ip-addr=127.0.0.1", 00072 "--ip-port=9788", 00073 "--beowulf-slaves=localhost:9790", 00074 "--beowulf-init-timeout=5.0", 0 }; 00075 00076 if (manager.parseCommandLine(5, argv, "", 0, 0) == false) 00077 return 1; 00078 00079 MYLOGVERB = LOG_DEBUG; 00080 00081 LINFO("starting..."); 00082 00083 manager.start(); 00084 00085 LINFO("... done starting"); 00086 00087 int rnode = 0; 00088 int32 rframe = 0, raction = 0; 00089 00090 LINFO("receiving..."); 00091 00092 bool gotit = false; 00093 00094 Timer t; 00095 00096 while (t.getSecs() < 10.0) 00097 { 00098 gotit = beomaster->receive(rnode, *rmsg, rframe, raction, 50); 00099 if (gotit) break; 00100 } 00101 00102 LINFO("gotit=%d", int(gotit)); 00103 00104 LINFO("exiting"); 00105 00106 return 0; 00107 } 00108 catch (...) 00109 { 00110 } 00111 00112 return 1; 00113 } 00114 00115 int run_slave(TCPmessage* msg) 00116 { 00117 try 00118 { 00119 MYLOGPREFIX = "slave"; 00120 00121 ModelManager manager("test-slave"); 00122 00123 nub::soft_ref<Beowulf> beoslave 00124 (new Beowulf(manager, "Beowulf Slave", "BeowulfSlave", false)); 00125 00126 manager.addSubComponent(beoslave); 00127 00128 const char* argv[] = { "test-slave", "--ip-addr=127.0.0.1", 00129 "--ip-port=9790", 0 }; 00130 00131 if (manager.parseCommandLine(3, argv, "", 0, 0) == false) 00132 return 1; 00133 00134 MYLOGVERB = LOG_DEBUG; 00135 00136 LINFO("starting..."); 00137 00138 manager.start(); 00139 00140 LINFO("... done starting"); 00141 00142 sleep(2); 00143 00144 LINFO("sending..."); 00145 beoslave->send(-1, *msg); 00146 LINFO("... done sending"); 00147 00148 volatile int signum = 0; 00149 catchsignals(&signum); 00150 00151 LINFO("waiting for a signal..."); 00152 00153 while (signum == 0) 00154 usleep(10000); 00155 00156 LINFO("... got signal %d", signum); 00157 00158 LINFO("exiting"); 00159 00160 return 0; 00161 } 00162 catch (...) 00163 { 00164 } 00165 00166 return 1; 00167 } 00168 } 00169 00170 static void beowulf_xx_basic_tcpmessage_xx_1(TestSuite& suite) 00171 { 00172 // ok, the basic idea here is that we spawn a beowulf slave process 00173 // and have it send a TCPmessage back to us in the parent process 00174 // where we try to receive that TCPmessage through a beowulf master 00175 // object, and then verify that the message has the expected 00176 // contents 00177 00178 Image<PixRGB<byte> > orig_colbyteima(4, 4, NO_INIT); 00179 Image<byte> orig_byteima(4, 4, NO_INIT); 00180 Image<float> orig_floatima(4, 4, NO_INIT); 00181 for (int i = 0; i < orig_colbyteima.getSize(); ++i) 00182 { 00183 orig_colbyteima.setVal(i, PixRGB<byte>(i, 2*i, 3*i)); 00184 orig_byteima.setVal(i, 4*i); 00185 orig_floatima.setVal(i, 0.5f*i); 00186 } 00187 const std::string orig_string("Hello, World!"); 00188 const int32 orig_int32 = 42; 00189 const int64 orig_int64 = std::numeric_limits<int64>::max(); 00190 const float orig_float = 1234.5678f; 00191 const double orig_double = 1.234567e8; 00192 00193 pid_t pid = fork(); 00194 00195 if (pid == 0) 00196 { 00197 // child 00198 00199 TCPmessage smsg; 00200 smsg.reset(0, 0); 00201 smsg.addImage(orig_colbyteima); 00202 smsg.addImage(orig_byteima); 00203 smsg.addImage(orig_floatima); 00204 smsg.addString(orig_string.c_str()); 00205 smsg.addInt32(orig_int32); 00206 smsg.addInt64(orig_int64); 00207 smsg.addFloat(orig_float); 00208 smsg.addDouble(orig_double); 00209 00210 exit(run_slave(&smsg)); 00211 } 00212 else 00213 { 00214 // parent 00215 00216 sleep(1); 00217 00218 TCPmessage rmsg; 00219 00220 int parentcode = run_master(&rmsg); 00221 REQUIRE_EQ(parentcode, 0); 00222 00223 kill(pid, SIGINT); 00224 00225 int childcode = -1; 00226 int c = 0; 00227 while (waitpid(pid, &childcode, WNOHANG) == 0) 00228 { 00229 usleep(10000); 00230 if (++c % 100 == 0) 00231 LINFO("waiting for child to exit"); 00232 } 00233 00234 bool no_exceptions = true; 00235 00236 try 00237 { 00238 const Image<PixRGB<byte> > cbi = rmsg.getElementColByteIma(); 00239 const Image<byte> bi = rmsg.getElementByteIma(); 00240 const Image<float> fi = rmsg.getElementFloatIma(); 00241 const std::string str = rmsg.getElementString(); 00242 const int32 i32 = rmsg.getElementInt32(); 00243 const int64 i64 = rmsg.getElementInt64(); 00244 const float f = rmsg.getElementFloat(); 00245 const double d = rmsg.getElementDouble(); 00246 00247 REQUIRE_EQ(cbi, orig_colbyteima); 00248 REQUIRE_EQ(bi, orig_byteima); 00249 REQUIRE_EQ(fi, orig_floatima); 00250 REQUIRE_EQ(str, orig_string); 00251 REQUIRE_EQ(i32, orig_int32); 00252 REQUIRE(i64 == orig_int64); 00253 REQUIRE_EQ(f, orig_float); 00254 REQUIRE_EQ(d, orig_double); 00255 } 00256 catch (...) 00257 { 00258 no_exceptions = false; 00259 } 00260 00261 REQUIRE(no_exceptions); 00262 } 00263 } 00264 00265 /////////////////////////////////////////////////////////////////////// 00266 // 00267 // main 00268 // 00269 /////////////////////////////////////////////////////////////////////// 00270 00271 int main(int argc, const char** argv) 00272 { 00273 TestSuite suite; 00274 00275 suite.ADD_TEST(beowulf_xx_basic_tcpmessage_xx_1); 00276 00277 suite.parseAndRun(argc, argv); 00278 00279 return 0; 00280 } 00281 00282 // ###################################################################### 00283 /* So things look consistent in everyone's emacs... */ 00284 /* Local Variables: */ 00285 /* mode: c++ */ 00286 /* indent-tabs-mode: nil */ 00287 /* End: */ 00288 00289 #endif // TESTSUITE_WHITEBOX_BEOWULF_C_DEFINED