windows build fixes and some more work on symtab serialization
[dyninst.git] / newtestsuite / src / test_lib.h
1 /*
2  * Copyright (c) 1996-2008 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #ifndef _test_lib_h_
43 #define _test_lib_h_
44
45 #include <iostream>
46 #include <typeinfo>
47 #include <stdexcept>
48 #include "ParameterDict.h"
49 #include "TestData.h"
50 #include "test_info_new.h"
51 #include "test_lib_dll.h"
52 #include <errno.h>
53 #include <assert.h>
54 #include <string.h>
55 #include <stdlib.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58
59 #if !defined(P_sleep)
60 #if defined(os_windows_test)
61 #define P_sleep(sec) Sleep(1000*(sec))
62 #define WIN32_LEAN_AND_MEAN
63 #include <windows.h>
64 #else
65 #define P_sleep(sec) sleep(sec)
66 #include <unistd.h>
67 #endif
68 #endif
69
70 #if defined(os_windows_test)
71 #include <direct.h>
72 #endif
73 #define DYNINST_NO_ERROR -1
74
75 #include "test_results.h"
76 #include "TestMutator.h"
77 #include "TestOutputDriver.h"
78 #include "comptester.h"
79
80 #define RETURNONFAIL(x) if ( x < 0 ) return FAILED;
81 #define RETURNONNULL(x) if ( x == NULL ) return FAILED;
82 #define PASS 0
83 #define FAIL -1
84
85 // New logging system
86 TESTLIB_DLL_EXPORT TestOutputDriver * getOutput();
87 TESTLIB_DLL_EXPORT void setOutput(TestOutputDriver * new_output);
88 // Set up the log files for test library output
89 TESTLIB_DLL_EXPORT void setOutputLog(FILE *log_fp);
90 TESTLIB_DLL_EXPORT void setErrorLog(FILE *log_fp);
91 TESTLIB_DLL_EXPORT FILE *getOutputLog();
92 TESTLIB_DLL_EXPORT FILE *getErrorLog();
93 TESTLIB_DLL_EXPORT void setOutputLogFilename(char *log_fn);
94 TESTLIB_DLL_EXPORT void setErrorLogFilename(char *log_fn);
95 TESTLIB_DLL_EXPORT const char *getOutputLogFilename();
96 TESTLIB_DLL_EXPORT const char *getErrorLogFilename();
97
98 // Functions to print messages to the log files
99 TESTLIB_DLL_EXPORT void logstatus(const char *fmt, ...);
100 TESTLIB_DLL_EXPORT void logerror(const char *fmt, ...);
101 TESTLIB_DLL_EXPORT void flushOutputLog();
102 TESTLIB_DLL_EXPORT void flushErrorLog();
103
104 // TODO Implement this function for Windows   
105 TESTLIB_DLL_EXPORT int setupMutatorsForRunGroup (RunGroup *group);
106
107
108 // Mutatee PID registration, for cleaning up hung mutatees
109 // TODO Check if these make any sense on Windows.  I suspect I'll need to
110 // change them.
111 TESTLIB_DLL_EXPORT void setPIDFilename(char *pfn);
112 TESTLIB_DLL_EXPORT char *getPIDFilename();
113 TESTLIB_DLL_EXPORT void registerPID(int pid);
114 TESTLIB_DLL_EXPORT void cleanPIDFile();
115
116 TESTLIB_DLL_EXPORT void setDebugPrint(int debug);
117 TESTLIB_DLL_EXPORT bool inTestList(test_data_t &test, std::vector<char *> &test_list);
118 TESTLIB_DLL_EXPORT int startNewProcessForAttach(const char *pathname, const char *argv[], FILE *outlog, FILE *errlog, bool attach);
119 TESTLIB_DLL_EXPORT void dprintf(const char *fmt, ...);
120 TESTLIB_DLL_EXPORT void addLibArchExt(char *dest, unsigned int dest_max_len, int psize);
121 TESTLIB_DLL_EXPORT int strcmpcase(char *s1, char *s2);
122 char *searchPath(const char *path, const char *file);
123
124 TESTLIB_DLL_EXPORT bool shouldRunTest(RunGroup *group, TestInfo *test);
125 TESTLIB_DLL_EXPORT void reportTestResult(RunGroup *group, TestInfo *test);
126
127 // loadOutputDriver loads an output driver plug-in and returns a pointer to
128 // the output driver implemented by it.
129 TESTLIB_DLL_EXPORT TestOutputDriver *loadOutputDriver(char *odname, void * data);
130
131 // Functions used for redirecting output e.g. to a temp file for entering into
132 // the database after running a test
133 TESTLIB_DLL_EXPORT int printout(char *fmt, ...);
134 TESTLIB_DLL_EXPORT int printerr(char *fmt, ...);
135 TESTLIB_DLL_EXPORT int printhuman(char *fmt, ...);
136
137 // Functions related to database output
138 TESTLIB_DLL_EXPORT void enableDBLog(TestInfo *test, RunGroup *runGroup);
139 TESTLIB_DLL_EXPORT void clearDBLog();
140
141 TESTLIB_DLL_EXPORT ComponentTester *getComponentTester();
142
143 #define EFAIL(cmsg) throw LocErr(__FILE__, __LINE__, std::string(cmsg))
144 #define REPORT_EFAIL catch(const LocErr &err) { \
145            err.print(stderr); \
146            return FAILED; }
147
148 class LocErr : public std::runtime_error 
149 {
150         std::string file__;
151         int line__;
152
153         public:
154
155         TESTLIB_DLL_EXPORT LocErr(const char * __file__,
156                         const int __line__,
157                         const std::string msg) :
158                 runtime_error(msg),
159                 file__(std::string(__file__)),
160                 line__(__line__)
161         {
162         }
163
164         TESTLIB_DLL_EXPORT virtual ~LocErr() throw() {}
165
166         TESTLIB_DLL_EXPORT std::string file() const
167         {
168                 return file__;
169         }
170
171         TESTLIB_DLL_EXPORT int line() const
172         {
173                 return line__;
174         }
175
176         TESTLIB_DLL_EXPORT void print(FILE * stream)  const
177         {
178                 fprintf(stream, "Error thrown from %s[%d]:\n\t\"%s\"\n",
179                                 file__.c_str(), line__, what());
180         }
181 };
182
183 class Tempfile {
184
185         //  file paths should be generalized to work on windows
186         char *fname;
187 #if !defined (os_windows_test)
188         int fd;
189 #else
190         HANDLE fd;
191 #endif
192
193         public:
194
195         Tempfile()
196         {
197 #if defined (os_windows_test)
198                 fname = (char *)malloc(1024 *sizeof (char));
199                 assert(fname);
200                 const char *dyninst_root = getenv("DYNINST_ROOT");
201                 char tmp_dir[1024];
202                 struct stat statbuf;
203
204                 if (!dyninst_root)
205                 {
206                         fprintf(stderr, "%s[%d]:  DYNINST_ROOT not specified\n", __FILE__, __LINE__);
207                         abort();
208                 }
209
210                 _snprintf(tmp_dir, 1024, "%s\temp", dyninst_root);
211
212                 if (0 != stat(tmp_dir, &statbuf))
213                 {
214                         if (ENOENT == errno)
215                         {
216                                 //  doesn't exist, make it
217                                 if (0 != _mkdir(tmp_dir))
218                                 {
219                                         fprintf(stderr, "%s[%d]:  mkdir: %s\n", __FILE__, __LINE__, strerror(errno));
220                                         abort();
221                                 }
222                         }
223                         else
224                         {
225                                 fprintf(stderr, "%s[%d]:  FIXME:  unexpected stat result: %s\n", 
226                                                 __FILE__, __LINE__, strerror(errno));
227                                 abort();
228                         }
229                 }
230
231                 if (0 != GetTempFileName(tmp_dir, "tempfile", 0, fname))
232                 {
233                         fprintf(stderr, "%s[%d]:  failed to create temp file name\n", __FILE__, __LINE__);
234                         assert(0);
235                 }
236
237                 fd = CreateFile(fname,  
238                                 GENERIC_READ | GENERIC_WRITE, // open r-w 
239                                 0,                    // do not share 
240                                 NULL,                 // default security 
241                                 CREATE_ALWAYS,        // overwrite existing
242                                 FILE_ATTRIBUTE_NORMAL,// normal file 
243                                 NULL);                // no template 
244
245                 if (fd == INVALID_HANDLE_VALUE) 
246                 { 
247                         fprintf(stderr, "%s[%d]:  failed to create temp file\n", __FILE__, __LINE__);
248                         assert(0);
249                 } 
250
251 #else
252                 fname = strdup("/tmp/tmpfileXXXXXX");
253                 fd = mkstemp(fname);
254
255                 if (-1 == fd)
256                 {
257                         fprintf(stderr, "%s[%d]:  failed to make temp file\n", __FILE__, __LINE__);
258                         abort();
259                 }
260 #endif
261         }
262
263         ~Tempfile()
264         {
265 #if defined (os_windows_test)
266                 if (0 == DeleteFile(fname))
267                 {
268                         fprintf(stderr, "%s[%d]:  DeleteFile failed: %s\n",
269                                         __FILE__, __LINE__, strerror(errno));
270                 }
271 #else
272                 if (0 != unlink (fname))
273                 {
274                         fprintf(stderr, "%s[%d]:  unlink failed: %s\n",
275                                         __FILE__, __LINE__, strerror(errno));
276                 }
277 #endif
278                 free (fname);
279         }
280
281         const char *getName()
282         {
283                 return fname;
284         }
285 };
286
287 #endif