On Wed, 30 Apr 2008, Robert Reif wrote:
[...]
> I am suppling a minimal patch to the alsa driver and a single wave test to
> illustrate this concept. I hope this allows valid tests to remain in spite of
> buggy windows drivers.
I think it should be a more general winetest concept. My idea is that
some platforms (e.g. Wine) could ask for stricter checks, by using
strict_wine a bit like they use todo_wine to request looser checks.
So for instance you would do:
strict_wine ok(expected_cond || buggy(this_is_a_bug), ...);
Then on Windows the test would pass if either expected_cond is true or
if this_is_a_bug is true. The same would happen for other platforms that
this test runs on (e.g. ReactOS).
However on Wine the strict_wine clause would cause buggy to always
return false. So on Wine this test would only succeed if expected_cond
is true.
In addition to buggy I would propose a deprecated(cond) macro which
would behave exactly the same but document valid but deprecated Windows
behavior that we really don't want to reproduce.
Finally it would also be possible to use strict_wine before skip() calls
to cause the skip() to fail if running on Wine (e.g. skipping due to a
missing API should not be allowed when Wine is known to implement that
API).
Now we don't want to pepper these all over the tests (especially
deprecated() and buggy()) so we'd need a strict policy for when to use
these.
I have attached a patch that implements an older incarnation of this
idea (instead of deprecated/buggy there was just ok_strict). I hope to
update it and submit it some day but in the meantime this can provide a
starting point.
--
Francois Gouget <[EMAIL PROTECTED]> http://fgouget.free.fr/
If it stinks, it's chemistry. If it moves, it's biology.
If it does not work, It's computer science.diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index fe3d3ff..ae0507a 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -263,7 +259,11 @@ static void test_hkey_main_Value_W(LPCWSTR name, LPCWSTR string,
ret = RegQueryValueExW(hkey_main, name, NULL, &type, NULL, &cbData);
GLE = GetLastError();
ok(ret == ERROR_SUCCESS, "RegQueryValueExW failed: %d, GLE=%d\n", ret, GLE);
- if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return;
+ if(GLE == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ strict_wine skip("RegQueryValueExW() is not implemented\n");
+ return;
+ }
ok(type == REG_SZ, "RegQueryValueExW returned type %d\n", type);
ok(cbData == full_byte_len,
@@ -556,7 +556,7 @@ static void test_enum_value(void)
res = RegSetValueExW( test_key, testW, 0, REG_SZ, (const BYTE *)foobarW, 7*sizeof(WCHAR) );
if (res==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
{
- skip("RegSetValueExW is not implemented\n");
+ strict_wine skip("RegSetValueExW is not implemented\n");
goto cleanup;
}
ok( res == 0, "RegSetValueExW failed error %d\n", res );
@@ -675,7 +675,7 @@ static void test_get_value(void)
if(!pRegGetValueA)
{
- skip("RegGetValue not available on this platform\n");
+ strict_wine skip("RegGetValue not available on this platform\n");
return;
}
@@ -775,7 +775,7 @@ static void test_get_value(void)
ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ, &type, NULL, &size);
ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
/* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */
- ok(size == strlen(sTestpath1)+1 || size == strlen(sTestpath1)+2,
+ strict_wine ok_strict(size == strlen(sTestpath1)+1, size == strlen(sTestpath1)+2,
"strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size);
ok(type == REG_SZ, "type=%d\n", type);
@@ -816,7 +816,7 @@ static void test_get_value(void)
ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size);
ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
/* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */
- ok((size == strlen(expanded)+1) || (size == strlen(sTestpath1)+1),
+ strict_wine ok_strict(size == strlen(expanded)+1, size == strlen(sTestpath1)+1,
"strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size);
ok(type == REG_SZ, "type=%d\n", type);
ok(!strcmp(expanded, buf), "expanded=\"%s\" buf=\"%s\"\n", expanded, buf);
@@ -826,7 +826,7 @@ static void test_get_value(void)
ret = pRegGetValueA(hkey_main, NULL, "TP2_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size);
ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
/* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath2 length + 1 here. */
- ok((size == strlen(expanded2)+1) || (size == strlen(sTestpath2)+1),
+ strict_wine ok_strict(size == strlen(expanded2)+1, size == strlen(sTestpath2)+1,
"strlen(expanded2)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size);
ok(type == REG_SZ, "type=%d\n", type);
ok(!strcmp(expanded2, buf), "expanded2=\"%s\" buf=\"%s\"\n", expanded2, buf);
@@ -844,7 +844,7 @@ static void test_get_value(void)
ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND, NULL, NULL, &size);
ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
/* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */
- ok(size == strlen(sTestpath1)+1 || size == strlen(sTestpath1)+2,
+ strict_wine ok_strict(size == strlen(sTestpath1)+1, size == strlen(sTestpath1)+2,
"strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size);
/* Query REG_EXPAND_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (type mismatch) */
@@ -1124,7 +1124,7 @@ static void test_regconnectregistry( void)
schnd = OpenSCManagerA( compName, NULL, GENERIC_READ);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
- skip("OpenSCManagerA is not implemented\n");
+ strict_wine skip("OpenSCManagerA is not implemented\n");
return;
}
@@ -1218,7 +1218,7 @@ static void test_reg_query_value(void)
ret = RegQueryValueW(subkey, NULL, valW, &size);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
- skip("RegQueryValueW is not implemented\n");
+ strict_wine skip("RegQueryValueW is not implemented\n");
goto cleanup;
}
ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret);
@@ -1266,7 +1266,7 @@ static void test_reg_delete_tree(void)
LONG size, ret;
if(!pRegDeleteTreeA) {
- skip("Skipping RegDeleteTreeA tests, function not present\n");
+ strict_wine skip("Skipping RegDeleteTreeA tests, function not present\n");
return;
}
diff --git a/include/wine/test.h b/include/wine/test.h
index 72cd84c..8d8383f 100644
--- a/include/wine/test.h
+++ b/include/wine/test.h
@@ -56,6 +56,9 @@ extern void winetest_set_location( const char* file, int line );
extern void winetest_start_todo( const char* platform );
extern int winetest_loop_todo(void);
extern void winetest_end_todo( const char* platform );
+extern void winetest_start_strict( const char* platform );
+extern int winetest_loop_strict(void);
+extern void winetest_end_strict( const char* platform );
extern int winetest_get_mainargs( char*** pargv );
extern void winetest_wait_child_process( HANDLE process );
@@ -68,25 +71,31 @@ extern void winetest_wait_child_process( HANDLE process );
#define START_TEST(name) void func_##name(void)
#endif
+extern int winetest_vok( int condition, const char *msg, va_list ap );
+
#ifdef __GNUC__
extern int winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) ));
+extern int winetest_ok_strict( int strict_condition, int relaxed_condition, const char *msg, ... ) __attribute__((format (printf,3,4) ));
extern void winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2)));
extern void winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2)));
#else /* __GNUC__ */
extern int winetest_ok( int condition, const char *msg, ... );
+extern int winetest_ok_strict( int strict_condition, int relaxed_condition, const char *msg, ... );
extern void winetest_skip( const char *msg, ... );
extern void winetest_trace( const char *msg, ... );
#endif /* __GNUC__ */
#define ok_(file, line) (winetest_set_location(file, line), 0) ? 0 : winetest_ok
+#define ok_strict_(file, line) (winetest_set_location(file, line), 0) ? 0 : winetest_ok_strict
#define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip
#define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace
#define ok ok_(__FILE__, __LINE__)
+#define ok_strict ok_strict_(__FILE__, __LINE__)
#define skip skip_(__FILE__, __LINE__)
#define trace trace_(__FILE__, __LINE__)
@@ -95,6 +104,11 @@ extern void winetest_trace( const char *msg, ... );
winetest_end_todo(platform))
#define todo_wine todo("wine")
+#define strict(platform) for (winetest_start_strict(platform); \
+ winetest_loop_strict(); \
+ winetest_end_strict(platform))
+#define strict_wine strict("wine")
+
#ifdef NONAMELESSUNION
# define U(x) (x).u
@@ -185,6 +199,8 @@ typedef struct
int current_line; /* line of current check */
int todo_level; /* current todo nesting level */
int todo_do_loop;
+ int strict_level; /* current strict nesting level */
+ int strict_do_loop;
} tls_data;
static DWORD tls_index;
@@ -234,9 +250,8 @@ void winetest_set_location( const char* file, int line )
* Return:
* 0 if condition does not have the expected value, 1 otherwise
*/
-int winetest_ok( int condition, const char *msg, ... )
+int winetest_vok( int condition, const char *msg, va_list args )
{
- va_list valist;
tls_data* data=get_tls_data();
if (data->todo_level)
@@ -247,10 +262,8 @@ int winetest_ok( int condition, const char *msg, ... )
data->current_file, data->current_line );
if (msg[0])
{
- va_start(valist, msg);
fprintf(stdout,": ");
- vfprintf(stdout, msg, valist);
- va_end(valist);
+ vfprintf(stdout, msg, args);
}
InterlockedIncrement(&todo_failures);
return 0;
@@ -265,10 +278,8 @@ int winetest_ok( int condition, const char *msg, ... )
data->current_file, data->current_line );
if (msg[0])
{
- va_start(valist, msg);
fprintf( stdout,": ");
- vfprintf(stdout, msg, valist);
- va_end(valist);
+ vfprintf(stdout, msg, args);
}
InterlockedIncrement(&failures);
return 0;
@@ -284,6 +295,29 @@ int winetest_ok( int condition, const char *msg, ... )
return 1;
}
+int winetest_ok( int condition, const char *msg, ... )
+{
+ va_list valist;
+ int rc;
+
+ va_start(valist, msg);
+ rc=winetest_vok(condition, msg, valist);
+ va_end(valist);
+ return rc;
+}
+
+int winetest_ok_strict( int strict_condition, int relaxed_condition, const char *msg, ... )
+{
+ va_list valist;
+ int rc;
+ tls_data* data=get_tls_data();
+
+ va_start(valist, msg);
+ rc=winetest_vok(strict_condition || (!data->strict_level && relaxed_condition), msg, valist);
+ va_end(valist);
+ return rc;
+}
+
void winetest_trace( const char *msg, ... )
{
va_list valist;
@@ -303,11 +337,20 @@ void winetest_skip( const char *msg, ... )
va_list valist;
tls_data* data=get_tls_data();
- fprintf( stdout, "%s:%d: Tests skipped: ", data->current_file, data->current_line );
- va_start(valist, msg);
- vfprintf(stdout, msg, valist);
- va_end(valist);
- skipped++;
+ if (data->strict_level)
+ {
+ va_start(valist, msg);
+ winetest_vok(0, msg, valist);
+ va_end(valist);
+ }
+ else
+ {
+ fprintf( stdout, "%s:%d: Tests skipped: ", data->current_file, data->current_line );
+ va_start(valist, msg);
+ vfprintf(stdout, msg, valist);
+ va_end(valist);
+ skipped++;
+ }
}
void winetest_start_todo( const char* platform )
@@ -335,6 +378,31 @@ void winetest_end_todo( const char* platform )
}
}
+void winetest_start_strict( const char* platform )
+{
+ tls_data* data=get_tls_data();
+ if (strcmp(winetest_platform,platform)==0)
+ data->strict_level++;
+ data->strict_do_loop=1;
+}
+
+int winetest_loop_strict(void)
+{
+ tls_data* data=get_tls_data();
+ int do_loop=data->strict_do_loop;
+ data->strict_do_loop=0;
+ return do_loop;
+}
+
+void winetest_end_strict( const char* platform )
+{
+ if (strcmp(winetest_platform,platform)==0)
+ {
+ tls_data* data=get_tls_data();
+ data->strict_level--;
+ }
+}
+
int winetest_get_mainargs( char*** pargv )
{
*pargv = winetest_argv;