Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / runTests-utils-nt.C
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #include <iostream>
32 #include <string>
33 #include <sstream>
34
35 #include <windows.h>
36 #include "runTests-utils.h"
37
38 using namespace std;
39
40 // configuration: timeout in seconds
41 int timeout = 1200;
42
43 void initPIDFilename(char *buffer, size_t len) {
44   _snprintf(buffer, len, "pids.windows.%lu", GetCurrentProcessId());
45 }
46
47 void cleanupMutatees(char *pidFilename) {
48   // TODO Fill this function in
49 }
50
51 //located in runTests.C
52 string ReplaceAllWith(const string &in, const string &replace, const string &with);
53
54 // SimpleShellEscape:
55 // Escapes some characters in the input string 
56 string SimpleShellEscape(string &str)
57 {
58    string tmp;
59    tmp = ReplaceAllWith(str, "*", "\\*");
60    tmp = ReplaceAllWith(tmp, "?", "\\?");
61    return tmp;
62 }
63
64 // RunTest:
65 // Sets up the command string to run the tests and executes test_driver
66 int RunTest(unsigned int iteration, bool useLog, bool staticTests,
67                         std::string logfile, int testLimit, std::vector<char *> child_argv,
68             char *pidFilename, char const * /*memcpu_file*/) {
69         string shellString;
70
71         generateTestString(iteration > 0, useLog, staticTests, logfile,
72         testLimit, child_argv, shellString, pidFilename);
73         
74         STARTUPINFO si;
75         PROCESS_INFORMATION pi;
76
77         memset(&si, 0, sizeof(si));
78         memset(&pi, 0, sizeof(pi));
79         si.cb = sizeof(si);
80         
81         // CreateProcess requires that this not be const
82         char * lpsz_shellString = (char *)malloc((shellString.length() + 1) * sizeof(char));
83         //TODO handle out of memory error
84         strcpy(lpsz_shellString, shellString.c_str());
85         
86         //execute
87         // -4 = we couldn't run test driver; thus if CreateProcess fails,
88         // we want to return something meaningful that will keep us from infinite
89         // looping
90         DWORD exitcode = -4;
91         if (CreateProcess(NULL, lpsz_shellString, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
92                 // wait for process, or timeout
93                 WaitForSingleObject(pi.hProcess, timeout * 1000);
94                 GetExitCodeProcess(pi.hProcess, &exitcode);
95                 CloseHandle(pi.hProcess);
96                 CloseHandle(pi.hThread);
97                 // TODO catch crash, etc
98         } else {
99                 // TODO failed to create process, handle error
100                 fprintf(stderr, "command line: %s\n", lpsz_shellString);
101                 fprintf(stderr, "[%s:%u] - Error creating process: error code %ld\n",
102                         __FILE__, __LINE__, GetLastError());
103         }
104
105         free(lpsz_shellString);
106         
107         return exitcode;
108 }
109
110 void generateTestString(bool resume, bool useLog, bool staticTests,
111                         string &logfile, int testLimit,
112                         vector<char *>& child_argv, string& shellString,
113                         char *pidFilename)
114 {
115    stringstream testString;
116    testString << "test_driver.exe -under-runtests -enable-resume -limit " << testLimit;
117    testString << " -pidfile " << pidFilename;
118
119    if ( resume )
120    {
121       testString << " -use-resume";
122    }
123    if ( useLog )
124    {
125      testString << " -log -logfile " << logfile.c_str();
126    }
127
128    // Add child's arguments
129    for ( unsigned int i = 0; i < child_argv.size(); i++ )
130    {
131       testString << " " << child_argv[i];
132    }
133    
134
135    shellString = testString.str();
136 }
137
138 char *setResumeEnv()
139 {
140    if ( getenv("RESUMELOG") != NULL )
141       return NULL;
142    
143    stringstream tmp;
144    tmp << "RESUMELOG=";
145    if ( getenv("TMP") )
146    {
147       tmp << getenv("TMP") << "\\";
148    }
149    else
150    {
151       tmp << "C:\\";
152    }
153
154    tmp << "test_driver.resumelog." << getpid();
155
156    char *r_tmp = strdup(tmp.str().c_str());
157    putenv(r_tmp);
158
159    return r_tmp;
160 }
161
162 // We don't need to do anything here, because on Windows . is
163 // explictly in the path.
164 char *setLibPath()
165 {
166    return NULL;
167 }
168
169 void setupVars(bool useLog, string &logfile)
170 {
171    if ( useLog && strlen(logfile.c_str()) == 0 )
172    {
173       cerr << "You must provide a logfile name after the -log option" << endl;
174       exit(1);
175    }
176    return;
177 }