Document how to cross-compile the tests with MinGW.
[wine] / documentation / testing.sgml
1   <chapter id="testing">
2     <title>Writing Conformance tests</title>
3
4     <para>
5       Note: This part of the documentation is still very much a work in
6       progress and is in no way complete.
7     </para>
8
9     <sect1 id="testing-intro">
10       <title>Introduction</title>
11       <para>
12         With more The Windows API follows no standard, it is itself a defacto
13         standard, and deviations from that standard, even small ones, often
14         cause applications to crash or misbehave in some way. Furthermore
15         a conformance test suite is the most accurate (if not necessarily
16         the most complete) form of API documentation and can be used to
17         supplement the Windows API documentation.
18       </para>
19       <para>
20         Writing a conformance test suite for more than 10000 APIs is no small
21         undertaking. Fortunately it can prove very useful to the development
22         of Wine way before it is complete.
23         <itemizedlist>
24           <listitem>
25             <para>
26               The conformance test suite must run on Windows. This is
27               necessary to provide a reasonable way to verify its accuracy.
28               Furthermore the tests must pass successfully on all Windows
29               platforms (tests not relevant to a given platform should be
30               skipped).
31             </para>
32             <para>
33               A consequence of this is that the test suite will provide a
34               great way to detect variations in the API between different
35               Windows versions. For instance, this can provide insights
36               into the differences between the, often undocumented, Win9x and
37               NT Windows families.
38             </para>
39             <para>
40               However, one must remember that the goal of Wine is to run
41               Windows applications on Linux, not to be a clone of any specific
42               Windows version. So such variations must only be tested for when
43               relevant to that goal.
44             </para>
45           </listitem>
46           <listitem>
47             <para>
48               Writing conformance tests is also an easy way to discover
49               bugs in Wine. Of course, before fixing the bugs discovered in
50               this way, one must first make sure that the new tests do pass
51               successfully on at least one Windows 9x and one Windows NT
52               version.
53             </para>
54             <para>
55               Bugs discovered this way should also be easier to fix. Unlike
56               some mysterious application crashes, when a conformance test
57               fails, the expected behavior and APIs tested for are known thus
58               greatly simplifying the diagnosis.
59             </para>
60           </listitem>
61           <listitem>
62             <para>
63               To detect regressions. Simply running the test suite regularly
64               in Wine turns it into a great tool to detect regressions.
65               When a test fails, one immediately knows what was the expected
66               behavior and which APIs are involved. Thus regressions caught
67               this way should be detected earlier, because it is easy to run
68               all tests on a regular basis, and easier to fix because of the
69               reduced diagnosis work.
70             </para>
71           </listitem>
72           <listitem>
73             <para>
74               Tests written in advance of the Wine development (possibly even
75               by non Wine developpers) can also simplify the work of the
76               futur implementer by making it easier for him to check the
77               correctness of his code.
78             </para>
79           </listitem>
80           <listitem>
81             <para>
82               Conformance tests will also come in handy when testing Wine on
83               new (or not as widely used) architectures such as FreeBSD,
84               Solaris x86 or even non-x86 systems. Even when the port does
85               not involve any significant change in the thread management,
86               exception handling or other low-level aspects of Wine, new
87               architectures can expose subtle bugs that can be hard to
88               diagnose when debugging regular (complex) applications.
89             </para>
90           </listitem>
91         </itemizedlist>
92       </para>
93     </sect1>
94
95
96     <sect1 id="testing-what">
97       <title>What to test for?</title>
98       <para>
99         The first thing to test for is the documented behavior of APIs
100         and such as CreateFile. For instance one can create a file using a
101         long pathname, check that the behavior is correct when the file
102         already exists, try to open the file using the corresponding short
103         pathname, convert the filename to Unicode and try to open it using
104         CreateFileW, and all other things which are documented and that
105         applications rely on.
106       </para>
107       <para>
108         While the testing framework is not specifically geared towards this
109         type of tests, it is also possible to test the behavior of Windows
110         messages. To do so, create a window, preferably a hidden one so that
111         it does not steal the focus when running the tests, and send messages
112         to that window or to controls in that window. Then, in the message
113         procedure, check that you receive the expected messages and with the
114         correct parameters.
115       </para>
116       <para>
117         For instance you could create an edit control and use WM_SETTEXT to
118         set its contents, possibly check length restrictions, and verify the
119         results using WM_GETTEXT. Similarly one could create a listbox and
120         check the effect of LB_DELETESTRING on the list's number of items,
121         selected items list, highlighted item, etc.
122       </para>
123       <para>
124         However, undocumented behavior should not be tested for unless there
125         is an application that relies on this behavior, and in that case the
126         test should mention that application, or unless one can strongly
127         expect applications to rely on this behavior, typically APIs that
128         return the required buffer size when the buffer pointer is NULL.
129       </para>
130     </sect1>
131
132
133     <sect1 id="testing-wine">
134       <title>Running the tests in Wine</title>
135       <para>
136         The simplest way to run the tests in Wine is to type 'make test' in
137         the Wine sources top level directory. This will run all the Wine
138         conformance tests.
139       </para>
140       <para>
141         The tests for a specific Wine library are located in a 'tests'
142         directory in that library's directory. Each test is contained in a
143         file (e.g. <filename>dlls/kernel/tests/thread.c</>). Each
144         file itself contains many checks concerning one or more related APIs.
145       </para>
146       <para>
147         So to run all the tests related to a given Wine library, go to the
148         corresponding 'tests' directory and type 'make test'. This will
149         compile the tests, run them, and create an '<replaceable>xxx</>.ok'
150         file for each test that passes successfully. And if you only want to
151         run the tests contained in the <filename>thread.c</> file of the
152         kernel library, you would do:
153 <screen>
154 <prompt>$ </>cd dlls/kernel/tests
155 <prompt>$ </>make thread.ok
156 </screen>
157       </para>
158       <para>
159         Note that if the test has already been run and is up to date (i.e. if
160         neither the kernel library nor the <filename>thread.c</> file has
161         changed since the <filename>thread.ok</> file was created), then make
162         will say so. To force the test to be re-run, delete the
163         <filename>thread.ok</> file, and run the make command again.
164       </para>
165       <para>
166         You can also run tests manually using a command similar to the
167         following:
168 <screen>
169 <prompt>$ </>../../../tools/runtest -q -M kernel32.dll -p kernel32_test.exe.so thread.c
170 <prompt>$ </>../../../tools/runtest -p kernel32_test.exe.so thread.c
171 thread.c: 86 tests executed, 5 marked as todo, 0 failures.
172 </screen>
173         The '-P wine' options defines the platform that is currently being
174         tested. Remove the '-q' option if you want the testing framework
175         to report statistics about the number of successful and failed tests.
176         Run <command>runtest -h</> for more details.
177       </para>
178     </sect1>
179
180
181     <sect1 id="testing-windows">
182       <title>Building and running the tests on Windows</title>
183       <sect2>
184         <title>Using pre-compiled binaries</title>
185         <para>
186           Unfortunately there are no pre-compiled binaries yet. However if
187           send an email to the Wine development list you can probably get
188           someone to send them to you, and maybe motivate some kind soul to
189           put in place a mechanism for publishing such binaries on a regular
190           basis.
191         </para>
192       </sect2>
193       <sect2>
194         <title>With Visual C++</title>
195         <itemizedlist>
196           <listitem><para>
197             get the Wine sources
198           </para></listitem>
199           <listitem><para>
200             Run msvcmaker to generate Visual C++ project files for the tests.
201             'msvcmaker' is a perl script so you may be able to run it on
202             Windows.
203 <screen>
204 <prompt>$ </>./tools/winapi/msvcmaker --no-wine
205 </screen>
206           </para></listitem>
207           <listitem><para>
208             If the previous steps were done on your Linux development
209             machine, make the Wine sources accessible to the Windows machine
210             on which you are going to compile them. Typically you would do
211             this using Samba but copying them altogether would work too.
212           </para></listitem>
213           <listitem><para>
214             On the Windows machine, open the <filename>winetest.dsw</>
215             workspace. This will load each test's project. For each test there
216             are two configurations: one compiles the test with the Wine
217             headers, and the other uses the Visual C++ headers. Some tests
218             will compile fine with the former, but most will require the
219             latter.
220           </para></listitem>
221           <listitem><para>
222             Open the <menuchoice><guimenu>Build</> <guimenu>Batch
223             build...</></> menu and select the tests and build configurations
224             you want to build. Then click on <guibutton>Build</>.
225           </para></listitem>
226           <listitem><para>
227             To run a specific test from Visual C++, go to
228             <menuchoice><guimenu>Project</> <guimenu>Settings...</></>. There
229             select that test's project and build configuration and go to the
230             <guilabel>Debug</> tab. There type the name of the specific test
231             to run (e.g. 'thread') in the <guilabel>Program arguments</>
232             field. Validate your change by clicking on <guibutton>Ok</> and
233             start the test by clicking the red exclamation mark (or hitting
234             'F5' or any other usual method).
235           </para></listitem>
236           <listitem><para>
237             You can also run the tests from the command line. You will find
238             them in either <filename>Output\Win32_Wine_Headers</> or
239             <filename>Output\Win32_MSVC_Headers</> depending on the build
240             method. So to run the kernel 'path' tests you would do:
241 <screen>
242 <prompt>C:\&gt;</>cd dlls\kernel\tests\Output\Win32_MSVC_Headers
243 <prompt>C:\dlls\kernel\tests\Output\Win32_MSVC_Headers&gt;</>kernel32_test thread
244 </screen>
245           </para></listitem>
246         </itemizedlist>
247       </sect2>
248       <sect2>
249         <title>With MinGW</title>
250         <para>
251           This needs to be documented. The best may be to ask on the Wine
252           development mailing list and update this documentation with the
253           result of your inquiry.
254         </para>
255       </sect2>
256       <sect2>
257         <title>Cross compiling with MinGW on Linux</title>
258         <para>
259           Here is how to generate Windows executables for the tests straight
260           from the comfort of Linux.
261         </para>
262         <itemizedlist>
263           <listitem><para>
264             First you need to get the MinGW cross-compiler. On Debian all
265             you need to do is type <command>apt-get install mingw32</>.
266           </para></listitem>
267           <listitem><para>
268             If you had already run <command>configure</>, then delete
269             <filename>config.cache</> and re-run <command>configure</>.
270             You can then run <command>make crosstest</>. To sum up:
271 <screen>
272 <prompt>$ </><userinput>rm config.cache</>
273 <prompt>$ </><userinput>./configure</>
274 <prompt>$ </><userinput>make crosstest</>
275 </screen>
276           </para></listitem>
277           <listitem><para>
278             If you get an error when compiling <filename>winsock.h</> then
279             you probably need to apply the following patch:
280             <ulink url="http://www.winehq.com/hypermail/wine-patches/2002/12/0157.html">http://www.winehq.com/hypermail/wine-patches/2002/12/0157.html</>
281           </para></listitem>
282         </itemizedlist>
283       </sect2>
284     </sect1>
285
286
287     <sect1 id="testing-test">
288       <title>Inside a test</title>
289
290       <para>
291         When writing new checks you can either modify an existing test file or
292         add a new one. If your tests are related to the tests performed by an
293         existing file, then add them to that file. Otherwise create a new .c
294         file in the tests directory and add that file to the
295         <varname>CTESTS</> variable in <filename>Makefile.in</>.
296       </para>
297       <para>
298         A new test file will look something like the following:
299 <screen>
300 #include &lt;wine/test.h&gt;
301 #include &lt;winbase.h&gt;
302
303 /* Maybe auxiliary functions and definitions here */
304
305 START_TEST(paths)
306 {
307    /* Write your checks there or put them in functions you will call from
308     * there
309     */
310 }
311 </screen>
312       </para>
313       <para>
314         The test's entry point is the START_TEST section. This is where
315         execution will start. You can put all your tests in that section but
316         it may be better to split related checks in functions you will call
317         from the START_TEST section. The parameter to START_TEST must match
318         the name of the C file. So in the above example the C file would be
319         called <filename>paths.c</>.
320       </para>
321       <para>
322         Tests should start by including the <filename>wine/test.h</> header.
323         This header will provide you access to all the testing framework
324         functions. You can then include the windows header you need, but make
325         sure to not include any Unix or Wine specific header: tests must
326         compile on Windows.
327       </para>
328 <!-- FIXME: Can we include windows.h now? We should be able to but currently __WINE__ is defined thus making it impossible. -->
329 <!-- FIXME: Add recommendations about what to print in case of a failure: be informative -->
330       <para>
331         You can use <function>trace</> to print informational messages. Note
332         that these messages will only be printed if 'runtest -v' is being used.
333 <screen>
334   trace("testing GlobalAddAtomA");
335   trace("foo=%d",foo);
336 </screen>
337       </para>
338       <para>
339         Then just call functions and use <function>ok</> to make sure that
340         they behaved as expected:
341 <screen>
342   ATOM atom = GlobalAddAtomA( "foobar" );
343   ok( GlobalFindAtomA( "foobar" ) == atom, "could not find atom foobar" );
344   ok( GlobalFindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR" );
345 </screen>
346         The first parameter of <function>ok</> is an expression which must
347         evaluate to true if the test was successful. The next parameter is a
348         printf-compatible format string which is displayed in case the test
349         failed, and the following optional parameters depend on the format
350         string.
351       </para>
352       <para>
353         It is important to display an informative message when a test fails:
354         a good error message will help the Wine developper identify exactly
355         what went wrong without having to add too many other printfs. For
356         instance it may be useful to print the error code if relevant, or the
357         expected value and effective value. In that respect, for some tests
358         you may want to define a macro such as the following:
359 <screen>
360 #define eq(received, expected, label, type) \
361         ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected))
362
363 ...
364
365 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
366 </screen>
367        </para>
368        <para>
369          Note
370        </para>
371     </sect1>
372
373
374     <sect1 id="testing-platforms">
375       <title>Handling platform issues</title>
376       <para>
377         Some checks may be written before they pass successfully in Wine.
378         Without some mechanism, such checks would potentially generate
379         hundred of known failures for months each time the tests are being run.
380         This would make it hard to detect new failures caused by a regression.
381         or to detect that a patch fixed a long standing issue.
382       </para>
383       <para>
384         Thus the Wine testing framework has the concept of platforms and
385         groups of checks can be declared as expected to fail on some of them.
386         In the most common case, one would declare a group of tests as
387         expected to fail in Wine. To do so, use the following construct:
388 <screen>
389 todo_wine {
390     SetLastError( 0xdeadbeef );
391     ok( GlobalAddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "failed to add atom 0" );
392 }
393 </screen>
394         On Windows the above check would be performed normally, but on Wine it
395         would be expected to fail, and not cause the failure of the whole
396         test. However. If that check were to succeed in Wine, it would
397         cause the test to fail, thus making it easy to detect when something
398         has changed that fixes a bug. Also note that todo checks are accounted
399         separately from regular checks so that the testing statistics remain
400         meaningful. Finally, note that todo sections can be nested so that if
401         a test only fails on the cygwin and reactos platforms, one would
402         write:
403 <screen>
404 todo("cygwin") {
405     todo("reactos") {
406         ...
407     }
408 }
409 </screen>
410         <!-- FIXME: Would we really have platforms such as reactos, cygwin, freebsd & co? -->
411         But specific platforms should not be nested inside a todo_wine section
412         since that would be redundant.
413       </para>
414       <para>
415         When writing tests you will also encounter differences between Windows
416         9x and Windows NT platforms. Such differences should be treated
417         differently from the platform issues mentioned above. In particular
418         you should remember that the goal of Wine is not to be a clone of any
419         specific Windows version but to run Windows applications on Unix.
420       </para>
421       <para>
422         So, if an API returns a different error code on Windows 9x and
423         Windows NT, your check should just verify that Wine returns one or
424         the other:
425 <screen>
426 ok ( GetLastError() == WIN9X_ERROR || GetLastError() == NT_ERROR, ...);
427 </screen>
428       </para>
429       <para>
430         If an API is only present on some Windows platforms, then use
431         LoadLibrary and GetProcAddress to check if it is implemented and
432         invoke it. Remember, tests must run on all Windows platforms.
433         Similarly, conformance tests should nor try to correlate the Windows
434         version returned by GetVersion with whether given APIs are
435         implemented or not. Again, the goal of Wine is to run Windows
436         applications (which do not do such checks), and not be a clone of a
437         specific Windows version.
438       </para>
439       <para>
440         FIXME: What about checks that cause the process to crash due to a bug?
441       </para>
442     </sect1>
443
444
445 <!-- FIXME: Strategies for testing threads, testing network stuff,
446  file handling, eq macro... -->
447
448   </chapter>
449
450 <!-- Keep this comment at the end of the file
451 Local variables:
452 mode: sgml
453 sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
454 End:
455 -->