Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
December 2017
- 60 participants
- 748 messages
[PATCH v2] d3dx9/tests: Use the available ARRAY_SIZE() macro.
by Matteo Bruni
From: Michael Stefaniuc <mstefani(a)winehq.org>
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Cleanup surrounding code a bit while at it.
dlls/d3dx9_36/tests/effect.c | 43 ++++++++++++++++++++++++++++---------------
dlls/d3dx9_36/tests/mesh.c | 26 ++++++++++++++++----------
2 files changed, 44 insertions(+), 25 deletions(-)
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 96b21f0454..1900f3eac1 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -1296,15 +1296,20 @@ static void test_effect_parameter_value_GetMatrix(const struct test_effect_param
const D3DXPARAMETER_DESC *res_desc = &res->desc;
const char *res_full_name = res->full_name;
HRESULT hr;
- DWORD cmp = 0xabababab;
- FLOAT fvalue[16];
+ union
+ {
+ DWORD d;
+ float f;
+ } cmp;
+ float fvalue[16];
UINT l, k, err = 0;
+ cmp.d = 0xabababab;
memset(fvalue, 0xab, sizeof(fvalue));
hr = effect->lpVtbl->GetMatrix(effect, parameter, (D3DXMATRIX *)&fvalue);
if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
{
- ok(hr == D3D_OK, "%u - %s: GetMatrix failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(hr == D3D_OK, "%u - %s: GetMatrix failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
for (k = 0; k < 4; ++k)
{
@@ -1322,12 +1327,14 @@ static void test_effect_parameter_value_GetMatrix(const struct test_effect_param
}
else
{
- ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrix failed, got %#x, expected %#x\n",
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrix failed, got %#x, expected %#x.\n",
i, res_full_name, hr, D3DERR_INVALIDCALL);
- for (l = 0; l < sizeof(fvalue) / sizeof(*fvalue); ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ for (l = 0; l < ARRAY_SIZE(fvalue); ++l)
+ if (fvalue[l] != cmp.f)
+ ++err;
}
- ok(!err, "%u - %s: GetMatrix failed with %u errors\n", i, res_full_name, err);
+ ok(!err, "%u - %s: GetMatrix failed with %u errors.\n", i, res_full_name, err);
}
static void test_effect_parameter_value_GetMatrixArray(const struct test_effect_parameter_value_result *res,
@@ -1451,15 +1458,20 @@ static void test_effect_parameter_value_GetMatrixTranspose(const struct test_eff
const D3DXPARAMETER_DESC *res_desc = &res->desc;
const char *res_full_name = res->full_name;
HRESULT hr;
- DWORD cmp = 0xabababab;
- FLOAT fvalue[16];
+ union
+ {
+ DWORD d;
+ float f;
+ } cmp;
+ float fvalue[16];
UINT l, k, err = 0;
+ cmp.d = 0xabababab;
memset(fvalue, 0xab, sizeof(fvalue));
hr = effect->lpVtbl->GetMatrixTranspose(effect, parameter, (D3DXMATRIX *)&fvalue);
if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
{
- ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
for (k = 0; k < 4; ++k)
{
@@ -1477,7 +1489,7 @@ static void test_effect_parameter_value_GetMatrixTranspose(const struct test_eff
}
else if (!res_desc->Elements && (res_desc->Class == D3DXPC_VECTOR || res_desc->Class == D3DXPC_SCALAR))
{
- ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
for (k = 0; k < 4; ++k)
{
@@ -1495,12 +1507,14 @@ static void test_effect_parameter_value_GetMatrixTranspose(const struct test_eff
}
else
{
- ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x\n",
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n",
i, res_full_name, hr, D3DERR_INVALIDCALL);
- for (l = 0; l < sizeof(fvalue) / sizeof(*fvalue); ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ for (l = 0; l < ARRAY_SIZE(fvalue); ++l)
+ if (fvalue[l] != cmp.f)
+ ++err;
}
- ok(!err, "%u - %s: GetMatrixTranspose failed with %u errors\n", i, res_full_name, err);
+ ok(!err, "%u - %s: GetMatrixTranspose failed with %u errors.\n", i, res_full_name, err);
}
static void test_effect_parameter_value_GetMatrixTransposeArray(const struct test_effect_parameter_value_result *res,
@@ -1674,8 +1688,7 @@ static void test_effect_parameter_value_ResetValue(const struct test_effect_para
static void test_effect_parameter_value(IDirect3DDevice9 *device)
{
- UINT i;
- UINT effect_count = sizeof(test_effect_parameter_value_data) / sizeof(*test_effect_parameter_value_data);
+ unsigned int effect_count = ARRAY_SIZE(test_effect_parameter_value_data), i;
for (i = 0; i < effect_count; ++i)
{
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c
index d0b1adb00e..82ae90ef75 100644
--- a/dlls/d3dx9_36/tests/mesh.c
+++ b/dlls/d3dx9_36/tests/mesh.c
@@ -818,7 +818,7 @@ static void test_fvf_decl_conversion(void)
};
unsigned int i;
- for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
+ for (i = 0; i < ARRAY_SIZE(test_data); ++i)
{
test_decl_to_fvf(test_data[i].decl, test_data[i].fvf, D3D_OK, __LINE__, i);
test_fvf_to_decl(test_data[i].fvf, test_data[i].decl, D3D_OK, __LINE__, i);
@@ -1185,12 +1185,15 @@ static void D3DXCreateMeshTest(void)
struct mesh mesh;
struct test_context *test_context;
- static const D3DVERTEXELEMENT9 decl1[3] = {
+ static const D3DVERTEXELEMENT9 decl1[] =
+ {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
- D3DDECL_END(), };
+ D3DDECL_END(),
+ };
- static const D3DVERTEXELEMENT9 decl2[] = {
+ static const D3DVERTEXELEMENT9 decl2[] =
+ {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 24, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0},
@@ -1201,7 +1204,8 @@ static void D3DXCreateMeshTest(void)
D3DDECL_END(),
};
- static const D3DVERTEXELEMENT9 decl3[] = {
+ static const D3DVERTEXELEMENT9 decl3[] =
+ {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
D3DDECL_END(),
@@ -1268,7 +1272,7 @@ static void D3DXCreateMeshTest(void)
if (hr == D3D_OK)
{
- size = sizeof(decl1) / sizeof(decl1[0]);
+ size = ARRAY_SIZE(decl1);
for (i = 0; i < size - 1; i++)
{
ok(test_decl[i].Stream == decl1[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl1[i].Stream);
@@ -1329,7 +1333,7 @@ static void D3DXCreateMeshTest(void)
if (hr == D3D_OK)
{
- size = sizeof(decl2) / sizeof(decl2[0]);
+ size = ARRAY_SIZE(decl2);
for (i = 0; i < size - 1; i++)
{
ok(test_decl[i].Stream == decl2[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl2[i].Stream);
@@ -1387,10 +1391,12 @@ static void D3DXCreateMeshFVFTest(void)
struct mesh mesh;
struct test_context *test_context;
- static const D3DVERTEXELEMENT9 decl[3] = {
+ static const D3DVERTEXELEMENT9 decl[] =
+ {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
- D3DDECL_END(), };
+ D3DDECL_END(),
+ };
hr = D3DXCreateMeshFVF(0, 0, 0, 0, NULL, NULL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
@@ -1453,7 +1459,7 @@ static void D3DXCreateMeshFVFTest(void)
if (hr == D3D_OK)
{
- size = sizeof(decl) / sizeof(decl[0]);
+ size = ARRAY_SIZE(decl);
for (i = 0; i < size - 1; i++)
{
ok(test_decl[i].Stream == decl[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl[i].Stream);
--
2.13.6
Dec. 29, 2017
[PATCH v2] quartz/tests: Fix resource leak.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/quartz/tests/filtergraph.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index e66dc40a3a..5fd3107208 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -486,6 +486,7 @@ static void test_render_with_multithread(void)
IFilterGraph2_Release(filter_graph);
IGraphBuilder_Release(graph_builder);
IClassFactory_Release(classfactory);
+ CloseHandle(thread);
CoUninitialize();
return;
}
--
2.13.6
Dec. 29, 2017
Re: update of pt_PT.po
by Zebediah Figura
The field should be filled in manually, yes. More importantly, however,
your patch needs a Signed-off-by header. See other patches for examples.
Thanks for your work!
On 12/27/2017 04:57 PM, Fernando wrote:
> Hi,
>
> I got the message below in reply to a translation patch. I used the
> script winepo to checkout the po file and obtain a diff.
>
> There is an "authorship" issue but I'm not sure how to proceed.
>
> I see: "Last-Translator: Automatically generated\n" in the po file.
> Shall I fill it in manually?
>
> Regards,
> Fernando Martins
>
> On 27 December 2017 at 21:46:26 +01:00, Marvin <testbot(a)winehq.org> wrote:
>> Thank you for your contribution to Wine!
>>
>> This is an automated notification to let you know that your patch has
>> been reviewed and its status set to "Authorship".
>>
>> This means that there are some authorship issues with your patch. The
>> author's full name, email address, or Signed-off-by headers are
>> missing or incorrectly formatted. You need to resend a patch with
>> corrected author information.
>>
>> If you do not understand the reason for this status, disagree with our
>> assessment, or are simply not sure how to proceed next, please ask for
>> clarification by replying to this email.
>
>
>
>
Dec. 29, 2017
[PATCH v2] ddraw/tests: Mark GetDC failures on VMware as broken
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
v2: Removed workarounds for DirectDraw 4 and 7, since VMWare already
passes the tests for those versions.
dlls/ddraw/tests/ddraw1.c | 12 ++++++------
dlls/ddraw/tests/ddraw2.c | 12 ++++++------
dlls/ddraw/tests/ddraw4.c | 2 +-
dlls/ddraw/tests/ddraw7.c | 2 +-
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 2c4410af78..90cd0b73b4 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -8999,15 +8999,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -9071,7 +9071,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 89d0d7e4be..6d3e090fff 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -10133,15 +10133,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -10205,7 +10205,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index fa1178d036..b280628f56 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -11767,7 +11767,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface4_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index fdfac696cf..846a83de08 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -11718,7 +11718,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface7_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
--
2.15.1
Dec. 29, 2017
[PATCH] user32/tests: Recognize undefined characters in OemKeyScan tests
by Alex Henrie
This reverts commit 72ab2d5b078d0ebad70a0baed29a80ce6b6c86ad.
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
My previous attempt did not resolve any of the test failures. It seems
that the problem is actually that OemToCharBuff always returns TRUE and
changes unmappable characters to question marks. However, because the
question mark character is character 3F in all OEM code pages, we can
safely assume that a question mark returned by OemToCharBuff for a
different OEM character indicates a character that cannot be mapped.
dlls/user32/tests/Makefile.in | 2 +-
dlls/user32/tests/input.c | 13 ++++++-------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in
index c71cbe2547..7149dc824e 100644
--- a/dlls/user32/tests/Makefile.in
+++ b/dlls/user32/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = user32.dll
-IMPORTS = user32 gdi32 advapi32 imm32
+IMPORTS = user32 gdi32 advapi32
C_SRCS = \
broadcast.c \
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index a15a64420d..030592b02f 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -54,7 +54,6 @@
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
-#include "imm.h"
#include "wine/test.h"
@@ -2516,23 +2515,23 @@ static void test_OemKeyScan(void)
DWORD ret, expect, vkey, scan;
WCHAR oem, wchr;
char oem_char;
- BOOL ime = ImmIsIME(GetKeyboardLayout(0));
for (oem = 0; oem < 0x200; oem++)
{
ret = OemKeyScan( oem );
oem_char = LOBYTE( oem );
- if (!OemToCharBuffW( &oem_char, &wchr, 1 ))
+ /* OemKeyScan returns -1 for any character that cannot be mapped,
+ * whereas OemToCharBuff changes unmappable characters to question
+ * marks. The ASCII characters 0-127, including the real question mark
+ * character, are all mappable and are the same in all OEM codepages. */
+ if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0))
expect = -1;
else
{
vkey = VkKeyScanW( wchr );
scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
- /* OemKeyScan returns -1 for any character that has to go through
- * the IME, whereas VkKeyScan returns the virtual key code for the
- * question mark key */
- if (!scan || (ime && wchr != '?' && vkey == VkKeyScanW( '?' )))
+ if (!scan)
expect = -1;
else
{
--
2.15.1
Dec. 29, 2017
[PATCH] ddraw/tests: Mark GetDC failures on VMware as broken
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ddraw/tests/ddraw1.c | 12 ++++++------
dlls/ddraw/tests/ddraw2.c | 12 ++++++------
dlls/ddraw/tests/ddraw4.c | 12 ++++++------
dlls/ddraw/tests/ddraw7.c | 12 ++++++------
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 2c4410af78..90cd0b73b4 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -8999,15 +8999,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -9071,7 +9071,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 89d0d7e4be..6d3e090fff 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -10133,15 +10133,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -10205,7 +10205,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index fa1178d036..6e68681f87 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -11694,15 +11694,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -11767,7 +11767,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface4_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index fdfac696cf..789e8308d8 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -11645,15 +11645,15 @@ static void test_getdc(void)
test_data[] =
{
{"D3DFMT_A8R8G8B8", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X8R8G8B8", {sizeof(test_data->format), DDPF_RGB, 0, {32},
- {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE},
+ {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_R5G6B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_X1R5G5B5", {sizeof(test_data->format), DDPF_RGB, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A1R5G5B5", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
- {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE},
+ {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE, DDERR_CANTCREATEDC /* VMware */},
{"D3DFMT_A4R4G4B4", {sizeof(test_data->format), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16},
{0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE, DDERR_CANTCREATEDC /* Vista+ */},
{"D3DFMT_X4R4G4B4", {sizeof(test_data->format), DDPF_RGB, 0, {16},
@@ -11718,7 +11718,7 @@ static void test_getdc(void)
dc = (void *)0x1234;
hr = IDirectDrawSurface7_GetDC(surface, &dc);
if (test_data[i].getdc_supported)
- ok(SUCCEEDED(hr) || (test_data[i].alt_result && hr == test_data[i].alt_result),
+ ok(SUCCEEDED(hr) || broken(hr == test_data[i].alt_result),
"Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
else
ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, test_data[i].name);
--
2.15.1
Dec. 29, 2017
[PATCH] testbot: Record and show status changes initiated by the administrator.
by Francois Gouget
This allows marking them as initiated by the administrator (which is
obvious when going in/out of maintenance but not otherwise).
Merge these records with the one the scheduler adds on its own to keep
the activity page clean.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/ObjectModel/CGI/FormPage.pm | 10 +++++++++-
testbot/lib/WineTestBot/Activity.pm | 12 +++++++++++-
testbot/web/admin/VMDetails.pl | 21 +++++++++++++++++++++
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/testbot/lib/ObjectModel/CGI/FormPage.pm b/testbot/lib/ObjectModel/CGI/FormPage.pm
index fb743a00..7489f835 100644
--- a/testbot/lib/ObjectModel/CGI/FormPage.pm
+++ b/testbot/lib/ObjectModel/CGI/FormPage.pm
@@ -358,7 +358,7 @@ sub SaveProperty($$$)
die "Pure virtual function FormPage::SaveProperty called";
}
-sub Save($)
+sub SaveProperties($)
{
my ($self) = @_;
@@ -389,6 +389,14 @@ sub Save($)
}
}
}
+ return 1;
+}
+
+sub Save($)
+{
+ my ($self) = @_;
+
+ return !1 if (!$self->SaveProperties());
my $ErrKey;
($ErrKey, $self->{ErrField}, $self->{ErrMessage}) = $self->{Collection}->Save();
diff --git a/testbot/lib/WineTestBot/Activity.pm b/testbot/lib/WineTestBot/Activity.pm
index d66109c0..c5d3b532 100644
--- a/testbot/lib/WineTestBot/Activity.pm
+++ b/testbot/lib/WineTestBot/Activity.pm
@@ -233,7 +233,17 @@ sub GetActivity($)
my $VMStatus = $StatusVMs->{$VM->Name};
if ($VMStatus)
{
- $LastVMStatus->{end} = $VMStatus->{start} if ($LastVMStatus);
+ if ($LastVMStatus and $LastVMStatus->{status} eq $VMStatus->{status} and
+ ($LastVMStatus->{details} || "") eq "administrator")
+ {
+ $VMStatus = $StatusVMs->{$VM->Name} = $LastVMStatus;
+ $LastStatusVMs{$VM->Name}->{$VM->Name} = {merged => 1, vmstatus => $VMStatus};
+ $VMStatus->{rows}++;
+ }
+ else
+ {
+ $LastVMStatus->{end} = $VMStatus->{start} if ($LastVMStatus);
+ }
}
elsif ($LastVMStatus and $LastVMStatus->{status} ne "engine")
{
diff --git a/testbot/web/admin/VMDetails.pl b/testbot/web/admin/VMDetails.pl
index f5e5520b..7b562a74 100644
--- a/testbot/web/admin/VMDetails.pl
+++ b/testbot/web/admin/VMDetails.pl
@@ -42,6 +42,27 @@ sub DisplayProperty($$)
return $self->SUPER::DisplayProperty($PropertyDescriptor);
}
+sub Save($)
+{
+ my ($self) = @_;
+
+ my $OldStatus = $self->{Item}->Status || "";
+ return !1 if (!$self->SaveProperties());
+
+ if ($OldStatus ne $self->{Item}->Status)
+ {
+ my ($ErrProperty, $ErrMessage) = $self->{Item}->Validate();
+ if (!defined $ErrMessage)
+ {
+ $self->{Item}->RecordStatus(undef, $self->{Item}->Status ." administrator");
+ }
+ }
+
+ my $ErrKey;
+ ($ErrKey, $self->{ErrField}, $self->{ErrMessage}) = $self->{Collection}->Save();
+ return ! defined($self->{ErrMessage});
+}
+
package main;
my $Request = shift;
--
2.15.1
Dec. 28, 2017
[PATCH] testbot/web: Add a statistics page.
by Francois Gouget
This can help figuring out how busy the TestBot is, whether the VMs must
be rebalanced to lighten the load on a VM host, whether reverts are
getting slow, etc.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Activity.pm | 165 ++++++++++++++-
testbot/lib/WineTestBot/CGI/PageBase.pm | 1 +
testbot/web/Stats.pl | 361 ++++++++++++++++++++++++++++++++
testbot/web/WineTestBot.css | 2 +
4 files changed, 528 insertions(+), 1 deletion(-)
create mode 100644 testbot/web/Stats.pl
diff --git a/testbot/lib/WineTestBot/Activity.pm b/testbot/lib/WineTestBot/Activity.pm
index c5d3b532..5a5d2328 100644
--- a/testbot/lib/WineTestBot/Activity.pm
+++ b/testbot/lib/WineTestBot/Activity.pm
@@ -35,7 +35,7 @@ use vars qw (@ISA @EXPORT);
require Exporter;
@ISA = qw(Exporter);
-(a)EXPORT = qw(&GetActivity);
+(a)EXPORT = qw(&GetActivity &GetStatistics);
=pod
@@ -289,4 +289,167 @@ sub GetActivity($)
return ($Activity, $Counters);
}
+sub _AddFullStat($$$;$)
+{
+ my ($Stats, $StatKey, $Value, $Source) = @_;
+
+ $Stats->{"$StatKey.count"}++;
+ $Stats->{$StatKey} += $Value;
+ my $MaxKey = "$StatKey.max";
+ if (!exists $Stats->{$MaxKey} or $Stats->{$MaxKey} < $Value)
+ {
+ $Stats->{$MaxKey} = $Value;
+ $Stats->{"$MaxKey.source"} = $Source if ($Source);
+ }
+}
+
+sub GetStatistics($)
+{
+ my ($VMs) = @_;
+
+ my ($GlobalStats, $HostsStats, $VMsStats) = ({}, {}, {});
+
+ my @JobTimes;
+ my $Jobs = CreateJobs();
+ foreach my $Job (@{$Jobs->GetItems()})
+ {
+ $GlobalStats->{"jobs.count"}++;
+
+ my $IsSpecialJob;
+ my $Steps = $Job->Steps;
+ foreach my $Step (@{$Steps->GetItems()})
+ {
+ my $StepType = $Step->Type;
+ $IsSpecialJob = 1 if ($StepType =~ /^(?:reconfig|suite)$/);
+
+ my $Tasks = $Step->Tasks;
+ foreach my $Task (@{$Tasks->GetItems()})
+ {
+ $GlobalStats->{"tasks.count"}++;
+ if ($Task->Started and $Task->Ended and
+ $Task->Status !~ /^(?:queued|running|canceled)$/)
+ {
+ my $Time = $Task->Ended - $Task->Started;
+ _AddFullStat($GlobalStats, "$StepType.time", $Time, $Task);
+ }
+ if ($IsSpecialJob)
+ {
+ my $ReportFileName = $Task->GetDir() . "/log";
+ if (-f $ReportFileName)
+ {
+ my $ReportSize = -s $ReportFileName;
+ _AddFullStat($GlobalStats, "$StepType.size", $ReportSize, $Task);
+ if ($VMs->ItemExists($Task->VM->GetKey()))
+ {
+ my $VMStats = ($VMsStats->{items}->{$Task->VM->Name} ||= {});
+ _AddFullStat($VMStats, "report.size", $ReportSize, $Task);
+ }
+ }
+ }
+ }
+ }
+
+ if (!$IsSpecialJob and$Job->Ended and
+ $Job->Status !~ /^(?:queued|running|canceled)$/)
+ {
+ my $Time = $Job->Ended - $Job->Submitted;
+ _AddFullStat($GlobalStats, "jobs.time", $Time, $Job);
+ push @JobTimes, $Time;
+
+ if (!exists $GlobalStats->{start} or $GlobalStats->{start} > $Job->Submitted)
+ {
+ $GlobalStats->{start} = $Job->Submitted;
+ }
+ if (!exists $GlobalStats->{end} or $GlobalStats->{end} < $Job->Ended)
+ {
+ $GlobalStats->{end} = $Job->Ended;
+ }
+ }
+ }
+
+ my $JobCount = $GlobalStats->{"jobs.time.count"};
+ if ($JobCount)
+ {
+ @JobTimes = sort { $a <=> $b } @JobTimes;
+ $GlobalStats->{"jobs.time.p10"} = $JobTimes[int($JobCount * 0.1)];
+ $GlobalStats->{"jobs.time.p50"} = $JobTimes[int($JobCount * 0.5)];
+ $GlobalStats->{"jobs.time.p90"} = $JobTimes[int($JobCount * 0.9)];
+ @JobTimes = (); # free early
+ }
+
+ my ($Activity, $Counters) = GetActivity($VMs);
+ $GlobalStats->{"recordgroups.count"} = $Counters->{recordgroups};
+ $GlobalStats->{"records.count"} = $Counters->{records};
+ foreach my $Group (values %$Activity)
+ {
+ if (!$VMsStats->{start} or $VMsStats->{start} > $Group->{start})
+ {
+ $VMsStats->{start} = $Group->{start};
+ }
+ if (!$VMsStats->{end} or $VMsStats->{end} < $Group->{end})
+ {
+ $VMsStats->{end} = $Group->{end};
+ }
+ next if (!$Group->{statusvms});
+
+ my ($IsGroupBusy, %IsHostBusy);
+ foreach my $VM (@{$VMs->GetItems()})
+ {
+ my $VMStatus = $Group->{statusvms}->{$VM->Name};
+ my $Host = $VMStatus->{vmstatus}->{host} || $VM->GetHost();
+ my $HostStats = ($HostsStats->{items}->{$Host} ||= {});
+
+ if (!$VMStatus->{merged})
+ {
+ my $VMStats = ($VMsStats->{items}->{$VM->Name} ||= {});
+ my $Status = $VMStatus->{status};
+
+ my $Time = $VMStatus->{end} - $VMStatus->{start};
+ _AddFullStat($VMStats, "$Status.time", $Time);
+ _AddFullStat($HostStats, "$Status.time", $Time);
+ if ($Status =~ /^(?:reverting|sleeping|running|dirty)$/)
+ {
+ $VMStats->{"busy.elapsed"} += $Time;
+ }
+
+ if ($VMStatus->{result} =~ /^(?:boterror|error|timeout)$/)
+ {
+ $VMStats->{"$VMStatus->{result}.count"}++;
+ $HostStats->{"$VMStatus->{result}.count"}++;
+ $GlobalStats->{"$VMStatus->{result}.count"}++;
+ }
+ elsif ($VMStatus->{task} and
+ ($VMStatus->{result} eq "completed" or
+ $VMStatus->{result} eq "failed"))
+ {
+ my $StepType = $VMStatus->{step}->Type;
+ _AddFullStat($VMStats, "$StepType.time", $Time, $VMStatus->{task});
+ _AddFullStat($HostStats, "$StepType.time", $Time, $VMStatus->{task});
+ }
+ }
+
+ $VMStatus = $VMStatus->{vmstatus};
+ if (!$IsHostBusy{$Host} and
+ $VMStatus->{status} =~ /^(?:reverting|sleeping|running|dirty)$/)
+ {
+ # Note that we cannot simply sum the VMs busy wall clock times to get
+ # the host busy wall clock time because this would count periods where
+ # more than one VM is busy multiple times.
+ $HostStats->{"busy.elapsed"} += $Group->{end} - $Group->{start};
+ $IsHostBusy{$Host} = 1;
+ $IsGroupBusy = 1;
+ }
+ }
+ if ($IsGroupBusy)
+ {
+ $GlobalStats->{"busy.elapsed"} += $Group->{end} - $Group->{start};
+ }
+ }
+ $GlobalStats->{elapsed} = $GlobalStats->{end} - $GlobalStats->{start};
+ $HostsStats->{elapsed} =
+ $VMsStats->{elapsed} = $VMsStats->{end} - $VMsStats->{start};
+
+ return { global => $GlobalStats, hosts => $HostsStats, vms => $VMsStats };
+}
+
1;
diff --git a/testbot/lib/WineTestBot/CGI/PageBase.pm b/testbot/lib/WineTestBot/CGI/PageBase.pm
index fe03a47e..14900904 100644
--- a/testbot/lib/WineTestBot/CGI/PageBase.pm
+++ b/testbot/lib/WineTestBot/CGI/PageBase.pm
@@ -266,6 +266,7 @@ EOF
print " <li><p><a href='", MakeSecureURL("/Submit.pl"),
"'>Submit job</a></p></li>\n";
print " <li><p><a href='/Activity.pl'>Activity</a></p></li>\n";
+ print " <li><p><a href='/Stats.pl'>Statistics</a></p></li>\n";
print " <li class='divider'> </li>\n";
print " <li><p><a href='", MakeSecureURL("/Logout.pl"), "'>Log out";
if (defined($Session))
diff --git a/testbot/web/Stats.pl b/testbot/web/Stats.pl
new file mode 100644
index 00000000..424d33e0
--- /dev/null
+++ b/testbot/web/Stats.pl
@@ -0,0 +1,361 @@
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# Shows TestBot statistics
+#
+# Copyright 2017 Francois Gouget
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+use strict;
+
+package StatsPage;
+
+use ObjectModel::CGI::Page;
+use ObjectModel::Collection;
+use WineTestBot::Config;
+use WineTestBot::Activity;
+use WineTestBot::Log;
+use WineTestBot::VMs;
+
+(a)StatsPage::ISA = qw(ObjectModel::CGI::Page);
+
+sub _initialize($$$)
+{
+ my ($self, $Request, $RequiredRole) = @_;
+
+ $self->{start} = Time();
+ $self->SUPER::_initialize($Request, $RequiredRole);
+}
+
+sub _GetDuration($;$)
+{
+ my ($Secs, $Raw) = @_;
+
+ return "n/a" if (!defined $Secs);
+
+ my @Parts;
+ if (!$Raw)
+ {
+ my $Mins = int($Secs / 60);
+ my $Hours = int($Mins / 60);
+ my $Days = int($Hours / 24);
+ push @Parts, "${Days}d" if ($Days);
+ my $Part = $Hours - 24 * $Days;
+ push @Parts, "${Part}h" if ($Part);
+ $Part = $Mins - 60 * $Hours;
+ push @Parts, "${Part}m" if ($Part);
+ $Secs = $Secs - 60 * $Mins;
+ }
+ push @Parts, (@Parts or int($Secs) == $Secs) ?
+ int($Secs) ."s" :
+ sprintf('%.1fs', $Secs);
+ return join(" ", @Parts);
+}
+
+sub _CompareVMs()
+{
+ my ($aHost, $bHost) = ($a->GetHost(), $b->GetHost());
+ if ($PrettyHostNames)
+ {
+ $aHost = $PrettyHostNames->{$aHost} || $aHost;
+ $bHost = $PrettyHostNames->{$bHost} || $bHost;
+ }
+ return $aHost cmp $bHost || $a->Name cmp $b->Name;
+}
+
+sub _AddRate($$;$)
+{
+ my ($Stats, $StatKey, $AllStats) = @_;
+
+ my $RateKey = $StatKey;
+ $RateKey =~ s/(?:\.time)?\.count$/.rate/;
+ $AllStats ||= $Stats;
+ $Stats->{$RateKey} = $AllStats->{elapsed} ?
+ 3600 * $Stats->{$StatKey} / $AllStats->{elapsed} :
+ "n/a";
+}
+
+sub _GetAverage($$)
+{
+ my ($Stats, $Key) = @_;
+ return "n/a" if (!$Stats->{"$Key.count"});
+ return $Stats->{$Key} / $Stats->{"$Key.count"};
+}
+
+my $NO_AVERAGE = 1;
+my $NO_PERCENTAGE = 2;
+my $NO_TIME = 4;
+
+sub _GetStatStr($$;$$)
+{
+ my ($Stats, $StatKey, $AllStats, $Flags) = @_;
+
+ if ($StatKey =~ /\.time$/ and !($Flags & $NO_AVERAGE) and
+ exists $Stats->{"$StatKey.count"})
+ {
+ my $Avg = _GetAverage($Stats, $StatKey);
+ return $Avg eq "n/a" ? "n/a" : _GetDuration($Avg, $Flags & $NO_TIME);
+ }
+
+ if ($StatKey =~ /\.size$/ and !($Flags & $NO_AVERAGE) and
+ exists $Stats->{"$StatKey.count"})
+ {
+ my $Avg = _GetAverage($Stats, $StatKey);
+ return $Avg eq "n/a" ? "n/a" : int($Avg);
+ }
+
+ my $Value = $Stats->{$StatKey};
+ if ($StatKey =~ /\.elapsed$/ and !($Flags & $NO_PERCENTAGE))
+ {
+ $AllStats ||= $Stats;
+ return "n/a" if (!$AllStats->{elapsed});
+ return sprintf('%.1f%', 100 * $Value / $AllStats->{elapsed});
+ }
+ if ($StatKey =~ /(?:\belapsed|\.time)\b/)
+ {
+ return _GetDuration($Value, $Flags & $NO_TIME);
+ }
+ if ($StatKey =~ /\.rate$/)
+ {
+ return sprintf('%.1f / h', $Value);
+ }
+ return "0" if (!exists $Stats->{$StatKey});
+ return $Value if ($Value == int($Value));
+ return sprintf('%.1f', $Value);
+}
+
+sub _GetStatHtml($$;$$)
+{
+ my ($Stats, $StatKey, $AllStats, $Flags) = @_;
+
+ my $Value = _GetStatStr($Stats, $StatKey, $AllStats, $Flags);
+ return $Value if (!$Stats->{"$StatKey.source"});
+
+ my $SrcObj = $Stats->{"$StatKey.source"};
+ my ($JobId, $StepNo, $TaskNo) = ObjectModel::Collection::SplitKey(undef, $SrcObj->GetFullKey());
+ if (defined $TaskNo)
+ {
+ my $Key = "$JobId#k". ($StepNo * 100 + $TaskNo);
+ return "<a href='/JobDetails.pl?Key=$Key'>$Value</a>";
+ }
+ return "<a href='/index.pl#job$JobId'>$Value</a>";
+}
+
+sub _GenGlobalLine($$$;$$)
+{
+ my ($Stats, $StatKey, $Label, $Description, $Flags) = @_;
+
+ my $Value = _GetStatHtml($Stats, $StatKey, undef, $Flags);
+ print "<tr><td>$Label</td><td>$Value</td><td>$Description</td></tr>\n";
+}
+
+sub _GenStatsLine($$$$;$)
+{
+ my ($RowStats, $StatKey, $Label, $ColumnKeys, $Flags) = @_;
+
+ print "<tr><td>$Label</td>\n";
+ foreach my $Col (@$ColumnKeys)
+ {
+ my $Stats = $RowStats->{items}->{$Col};
+ my $Value = _GetStatHtml($Stats, $StatKey, $RowStats, $Flags);
+ print "<td>$Value</td>\n";
+ }
+ print "</tr>\n";
+}
+
+sub GenerateBody($)
+{
+ my ($self) = @_;
+
+ print "<h1>${ProjectName} Test Bot activity statistics</h1>\n";
+ print "<div class='Content'>\n";
+
+ ### Get the sorted VMs list
+
+ my $VMs = CreateVMs();
+ $VMs->FilterEnabledRole();
+ my @SortedVMs = sort _CompareVMs @{$VMs->GetItems()};
+ my $Stats = GetStatistics($VMs);
+
+ ### Show global statistics
+
+ my $GlobalStats = $Stats->{global};
+ print "<h2>General statistics</h2>\n";
+ print "<div class='CollectionBlock'><table>\n";
+
+ print "<thead><tr><th>Stat</th><th>Value</th><th>Description</th></thead>\n";
+ print "<tbody>\n";
+
+ _GenGlobalLine($GlobalStats, "elapsed", "Job history", "How far back the job history goes.");
+
+ _GenGlobalLine($GlobalStats, "jobs.count", "Job count", "The number of jobs in the job history.");
+ _AddRate($GlobalStats, "jobs.count");
+ _GenGlobalLine($GlobalStats, "jobs.rate", "Job rate", "How fast new jobs are coming in.");
+ _GenGlobalLine($GlobalStats, "tasks.count", "Task count", "The number of tasks.");
+ _AddRate($GlobalStats, "tasks.count");
+ _GenGlobalLine($GlobalStats, "tasks.rate", "Task rate", "How fast new tasks are coming in.");
+ _GenGlobalLine($GlobalStats, "busy.elapsed", "Busy time", "How much wall clock time was spent running jobs.", $NO_PERCENTAGE);
+ _GenGlobalLine($GlobalStats, "busy.elapsed", "Busy \%", "The percentage of wall clock time where the TestBot was busy running jobs.");
+
+ print "<tr><td class='StatSeparator'>Job times</td><td colspan='2'><hr></td></tr>\n";
+ _GenGlobalLine($GlobalStats, "jobs.time.p10", "10%", "10% of the jobs completed within this time.");
+ _GenGlobalLine($GlobalStats, "jobs.time.p50", "50%", "50% of the jobs completed within this time.");
+ _GenGlobalLine($GlobalStats, "jobs.time.p90", "90%", "90% of the jobs completed within this time.");
+ _GenGlobalLine($GlobalStats, "jobs.time.max", "Max", "The slowest job took this long. Note that this is heavily influenced by test storms.");
+
+ print "<tr><td class='StatSeparator'>Average times</td><td colspan='2'><hr></td></tr>\n";
+ _GenGlobalLine($GlobalStats, "jobs.time", "Job completion", "How long it takes to complete a regular job (excluding canceled ones). Note that this is heavily influenced by test storms.");
+ _GenGlobalLine($GlobalStats, "reconfig.time", "Wine update", "How long the daily Wine update takes.");
+ _GenGlobalLine($GlobalStats, "suite.time", "WineTest", "Average time for a WineTest run.");
+ _GenGlobalLine($GlobalStats, "build.time", "Build", "Average patch build time.");
+ _GenGlobalLine($GlobalStats, "single.time", "Test", "Average test run time. Note that this very much depends on the tests and how many time out on a given day.");
+
+ print "<tr><td class='StatSeparator'>WineTest reports</td><td colspan='2'><hr></td></tr>\n";
+ _GenGlobalLine($GlobalStats, "suite.size", "Average size", "Average WineTest report size.");
+ _GenGlobalLine($GlobalStats, "suite.size.max", "Max size", "Maximum WineTest report size.");
+
+ print "<tr><td class='StatSeparator'>Errors</td><td colspan='2'><hr></td></tr>\n";
+ _GenGlobalLine($GlobalStats, "timeout.count", "Timeouts", "How many timeouts occurred, either because of a test bug or a TestBot performance issue.");
+ _GenGlobalLine($GlobalStats, "boterror.count", "TestBot errors", "How many tasks failed due to a TestBot error.");
+ _GenGlobalLine($GlobalStats, "error.count", "Transient errors", "How many transient (network?) errors happened and caused the task to be re-run.");
+
+ print "<tr><td class='StatSeparator'>Activity</td><td colspan='2'><hr></td></tr>\n";
+ my $VMsStats = $Stats->{vms};
+ _GenGlobalLine($VMsStats, "elapsed", "Activity history", "How far the activity records go. This is used for the VM and VM host tables.");
+ _GenGlobalLine($GlobalStats, "records.count", "Record count", "The number of activity records.");
+
+ print "</tbody></table></div>\n";
+
+ ### Generate a table with the VM host statistics
+
+ print "<p></p>\n";
+ print "<h2>VM host statistics</h2>\n";
+ print "<div class='CollectionBlock'><table>\n";
+
+ print "<thead><tr><th>Stat</th>\n";
+ my $HostsStats = $Stats->{hosts};
+ my $SortedHosts = [ sort keys %{$Stats->{hosts}->{items}} ];
+ foreach my $Host (@$SortedHosts)
+ {
+ my $DisplayHost = $Host;
+ if ($PrettyHostNames and defined $PrettyHostNames->{$Host})
+ {
+ $DisplayHost = $PrettyHostNames->{$Host};
+ }
+ $DisplayHost ||= "localhost";
+ print "<th>$DisplayHost</th>\n";
+
+ _AddRate($HostsStats->{items}->{$Host}, "reverting.time.count", $HostsStats);
+ _AddRate($HostsStats->{items}->{$Host}, "running.time.count", $HostsStats);
+ }
+ print "</tr></thead>\n";
+
+ print "<tbody>\n";
+ _GenStatsLine($HostsStats, "reverting.time.count", "Revert count", $SortedHosts);
+ _GenStatsLine($HostsStats, "reverting.rate", "Revert rate", $SortedHosts);
+ _GenStatsLine($HostsStats, "running.time.count", "Task count", $SortedHosts);
+ _GenStatsLine($HostsStats, "running.rate", "Task rate", $SortedHosts);
+ _GenStatsLine($HostsStats, "busy.elapsed", "Busy time", $SortedHosts, $NO_PERCENTAGE);
+ _GenStatsLine($HostsStats, "busy.elapsed", "Busy \%", $SortedHosts);
+
+ print "<tr><td class='StatSeparator'>Average times</td><td colspan='", scalar(@$SortedHosts),"'><hr></td></tr>\n";
+ _GenStatsLine($HostsStats, "reverting.time", "Revert", $SortedHosts);
+ _GenStatsLine($HostsStats, "sleeping.time", "Sleep", $SortedHosts);
+ _GenStatsLine($HostsStats, "running.time", "Run", $SortedHosts);
+ _GenStatsLine($HostsStats, "dirty.time", "Dirty", $SortedHosts);
+ _GenStatsLine($HostsStats, "offline.time", "Offline", $SortedHosts);
+ _GenStatsLine($HostsStats, "suite.time", "WineTest", $SortedHosts);
+
+ print "<tr><td class='StatSeparator'>Maximum times</td><td colspan='", scalar(@$SortedHosts),"'><hr></td></tr>\n";
+ _GenStatsLine($HostsStats, "reverting.time.max", "Revert", $SortedHosts);
+ _GenStatsLine($HostsStats, "sleeping.time.max", "Sleep", $SortedHosts);
+ _GenStatsLine($HostsStats, "running.time.max", "Run", $SortedHosts);
+ _GenStatsLine($HostsStats, "dirty.time.max", "Dirty", $SortedHosts);
+ _GenStatsLine($HostsStats, "offline.time.max", "Offline", $SortedHosts);
+ _GenStatsLine($HostsStats, "suite.time.max", "WineTest", $SortedHosts);
+
+ print "<tr><td class='StatSeparator'>Errors</td><td colspan='", scalar(@$SortedHosts),"'><hr></td></tr>\n";
+ _GenStatsLine($HostsStats, "timeout.count", "Timeouts", $SortedHosts);
+ _GenStatsLine($HostsStats, "boterror.count", "TestBot errors", $SortedHosts);
+ _GenStatsLine($HostsStats, "error.count", "Transient errors", $SortedHosts);
+
+ print "</tbody></table></div>\n";
+
+ ### Generate a table with the VM statistics
+
+ print "<p></p>\n";
+ print "<h2>VM statistics</h2>\n";
+ print "<div class='CollectionBlock'><table>\n";
+
+ print "<thead><tr><th>Stat</th>\n";
+ my $SortedVMKeys;
+ foreach my $VM (@SortedVMs)
+ {
+ my $Host = $VM->GetHost();
+ if ($PrettyHostNames and defined $PrettyHostNames->{$Host})
+ {
+ $Host = $PrettyHostNames->{$Host};
+ }
+ $Host = " on $Host" if ($Host ne "");
+ print "<th>", $VM->Name, "$Host</th>\n";
+ push @$SortedVMKeys, $VM->Name;
+
+ _AddRate($VMsStats->{items}->{$VM->Name}, "reverting.time.count", $VMsStats);
+ _AddRate($VMsStats->{items}->{$VM->Name}, "running.time.count", $VMsStats);
+ }
+ print "</tr></thead>\n";
+
+ print "<tbody>\n";
+ _GenStatsLine($VMsStats, "reverting.time.count", "Revert count", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "reverting.rate", "Revert rate", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "running.time.count", "Task count", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "running.rate", "Task rate", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "busy.elapsed", "Busy time", $SortedVMKeys, $NO_PERCENTAGE);
+ _GenStatsLine($VMsStats, "busy.elapsed", "Busy \%", $SortedVMKeys);
+
+ print "<tr><td class='StatSeparator'>Average times</td><td colspan='", scalar(@$SortedVMKeys),"'><hr></td></tr>\n";
+ _GenStatsLine($VMsStats, "reverting.time", "Revert", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "sleeping.time", "Sleep", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "running.time", "Run", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "dirty.time", "Dirty", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "offline.time", "Offline", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "suite.time", "WineTest", $SortedVMKeys);
+
+ print "<tr><td class='StatSeparator'>Maximum times</td><td colspan='", scalar(@$SortedVMKeys),"'><hr></td></tr>\n";
+ _GenStatsLine($VMsStats, "reverting.time.max", "Revert", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "sleeping.time.max", "Sleep", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "running.time.max", "Run", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "dirty.time.max", "Dirty", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "offline.time.max", "Offline", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "suite.time.max", "WineTest", $SortedVMKeys);
+
+ print "<tr><td class='StatSeparator'>WineTest/Reconfig reports</td><td colspan='", scalar(@$SortedVMKeys),"'><hr></td></tr>\n";
+ _GenStatsLine($VMsStats, "report.size", "Average size", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "report.size.max", "Max size", $SortedVMKeys);
+
+ print "<tr><td class='StatSeparator'>Errors</td><td colspan='", scalar(@$SortedVMKeys),"'><hr></td></tr>\n";
+ _GenStatsLine($VMsStats, "timeout.count", "Timeouts", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "boterror.count", "TestBot errors", $SortedVMKeys);
+ _GenStatsLine($VMsStats, "error.count", "Transient errors", $SortedVMKeys);
+
+ print "</tbody></table></div>\n";
+ print "<p class='GeneralFooterText'>Generated in ", Elapsed($self->{start}), " s</p>\n";
+}
+
+package main;
+
+my $Request = shift;
+
+my $StatsPage = StatsPage->new($Request, "wine-devel");
+$StatsPage->GeneratePage();
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 4afbe31c..2ccce246 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -376,3 +376,5 @@ td.Record { text-align: center; }
.Record.Record-error { border-left: thick solid #990000; border-right: thick solid #990000; }
.Record.Record-timeout { border-left: thick solid blue; border-right: thick solid blue; }
.Record.Record-miss { border-top: thick dashed #ff6600; }
+
+td.StatSeparator { color: #601919; font-weight: bold; }
--
2.15.1
Dec. 28, 2017
Re: [PATCH] quartz: Enhancement for AVISplitter_create.
by Alexandre Julliard
Andrey Gusev <andrey.goosev(a)gmail.com> writes:
> @@ -1442,13 +1442,20 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
> /* Note: This memory is managed by the transform filter once created */
> This = CoTaskMemAlloc(sizeof(AVISplitterImpl));
>
> - This->streams = NULL;
> - This->oldindex = NULL;
> + if (!This)
> + return E_OUTOFMEMORY;
>
> + ZeroMemory(This, sizeof(AVISplitterImpl));
What is this fixing?
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 28, 2017
Re: [PATCH] quartz/tests: Fix resource leak.
by Alexandre Julliard
Andrey Gusev <andrey.goosev(a)gmail.com> writes:
> @@ -487,7 +487,7 @@ static void test_render_with_multithread(void)
> IGraphBuilder_Release(graph_builder);
> IClassFactory_Release(classfactory);
> CoUninitialize();
> - return;
> + return thread;
This doesn't make any sense, it won't even compile.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 28, 2017