1 /*
2  * PROJECT:     ReactOS Automatic Testing Utility
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Main implementation file
5  * COPYRIGHT:   Copyright 2008-2009 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 #include <cstdio>
10 
11 CConfiguration Configuration;
12 
13 /**
14  * Prints the application usage.
15  */
16 static void
17 IntPrintUsage()
18 {
19     cout << "rosautotest - ReactOS Automatic Testing Utility" << endl
20          << "Usage: rosautotest [options] [module] [test]" << endl
21          << "  options:" << endl
22          << "    /?           - Shows this help." << endl
23          << "    /c <comment> - Specifies the comment to be submitted to the Web Service." << endl
24          << "                   Skips the comment set in the configuration file (if any)." << endl
25          << "                   Only has an effect when /w is also used." << endl
26          << "    /n           - Do not print test output to console" << endl
27          << "    /r           - Maintain information to resume from ReactOS crashes" << endl
28          << "                   Can only be run under ReactOS and relies on sysreg2," << endl
29          << "                   so incompatible with /w" << endl
30          << "    /s           - Shut down the system after finishing the tests." << endl
31          << "    /t <num>     - Repeat the test <num> times (1-10000)" << endl
32          << "    /w           - Submit the results to the webservice." << endl
33          << "                   Requires a \"rosautotest.ini\" with valid login data." << endl
34          << "                   Incompatible with the /r option." << endl
35          << "    /l           - List all modules that would run." << endl
36          << endl
37          << "  module:" << endl
38          << "    The module to be tested (i.e. \"advapi32\")" << endl
39          << "    If this parameter is specified without any test parameter," << endl
40          << "    all tests of the specified module are run." << endl
41          << endl
42          << "  test:" << endl
43          << "    The test to be run. Needs to be a test of the specified module." << endl;
44 }
45 
46 /**
47  * Main entry point
48  */
49 extern "C" int
50 wmain(int argc, wchar_t* argv[])
51 {
52     int ReturnValue = 1;
53 
54     try
55     {
56         stringstream ss;
57 
58         /* Set up the configuration */
59         Configuration.ParseParameters(argc, argv);
60         Configuration.GetSystemInformation();
61         Configuration.GetConfigurationFromFile();
62 
63         ss << endl
64            << endl
65            << "[ROSAUTOTEST] System uptime " << setprecision(2) << fixed;
66         ss << ((float)GetTickCount()/1000) << " seconds" << endl;
67         StringOut(ss.str());
68 
69         /* Report tests startup */
70         InitLogs();
71         ReportEventW(hLog,
72                       EVENTLOG_INFORMATION_TYPE,
73                       0,
74                       MSG_TESTS_STARTED,
75                       NULL,
76                       0,
77                       0,
78                       NULL,
79                       NULL);
80 
81         if (Configuration.GetRepeatCount() > 1)
82         {
83             stringstream ss1;
84 
85             ss1 << "[ROSAUTOTEST] The test will be repeated " << Configuration.GetRepeatCount() << " times" << endl;
86             StringOut(ss1.str());
87         }
88 
89         /* Run the tests */
90         for (unsigned long i = 0; i < Configuration.GetRepeatCount(); i++)
91         {
92             CWineTest WineTest;
93 
94             if (Configuration.GetRepeatCount() > 1)
95             {
96                 stringstream ss;
97                 ss << "[ROSAUTOTEST] Running attempt #" << i+1 << endl;
98                 StringOut(ss.str());
99             }
100             WineTest.Run();
101         }
102 
103         /* For sysreg2 */
104         DbgPrint("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
105 
106         ReturnValue = 0;
107     }
108     catch(CInvalidParameterException)
109     {
110         IntPrintUsage();
111     }
112     catch(CSimpleException& e)
113     {
114         stringstream ss;
115 
116         // e.GetMessage() must include ending '\n'.
117         ss << "[ROSAUTOTEST] " << e.GetMessage();
118         StringOut(ss.str());
119     }
120     catch(CFatalException& e)
121     {
122         stringstream ss;
123 
124         // e.GetMessage() must include ending '\n'.
125         ss << "An exception occured in rosautotest." << endl
126            << "Message: " << e.GetMessage()
127            << "File: " << e.GetFile() << endl
128            << "Line: " << e.GetLine() << endl
129            << "Last Win32 Error: " << GetLastError() << endl;
130         StringOut(ss.str());
131     }
132 
133     /* For sysreg2 to notice if rosautotest itself failed */
134     if(ReturnValue == 1)
135         DbgPrint("SYSREG_ROSAUTOTEST_FAILURE\n");
136 
137     /* Report successful end of tests */
138     ReportEventW(hLog,
139                   EVENTLOG_SUCCESS,
140                   0,
141                   MSG_TESTS_SUCCESSFUL,
142                   NULL,
143                   0,
144                   0,
145                   NULL,
146                   NULL);
147     FreeLogs();
148 
149     /* Shut down the system if requested, also in case of an exception above */
150     if(Configuration.DoShutdown() && !ShutdownSystem())
151         ReturnValue = 1;
152 
153     return ReturnValue;
154 }
155