On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 99 ++++++++++++++++++++---- 1 file changed, 83 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 908e04bb0c3..3766572177f 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -247,8 +247,8 @@ struct compilation_handler IAsyncHandler_Compilation IAsyncHandler_Compilation_iface; LONG ref;
- HANDLE event_block; HANDLE event_finished;
- BOOLEAN sleeping; DWORD thread_id; };
@@ -298,8 +298,10 @@ HRESULT WINAPI compilation_handler_Invoke( IAsyncHandler_Compilation *iface, trace("Iface %p, info %p, status %d.\n", iface, info, status); trace("Caller thread id %lu callback thread id %lu.\n", impl->thread_id, id);
- ok(status != Started, "Got unexpected status %#x.\n", status);
/* Signal finishing of the handler. */ if (impl->event_finished) SetEvent(impl->event_finished);
/* Block handler until event is set. */
if (impl->event_block) WaitForSingleObject(impl->event_block, INFINITE);
return S_OK; }
@@ -821,6 +823,23 @@ static void test_VoiceInformation(void) RoUninitialize(); }
+struct async_operation_block_param +{
- IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult *handler;
- IAsyncOperation_SpeechRecognitionCompilationResult *operation;
+};
+static DWORD WINAPI async_operation_block_thread(void *arg) +{
- struct async_operation_block_param *param = arg;
- HRESULT hr;
- hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(param->operation, param->handler);
- ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- return 0;
+}
- static void test_SpeechRecognizer(void) { static const WCHAR *speech_recognition_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer";
@@ -836,17 +855,17 @@ static void test_SpeechRecognizer(void) ISpeechRecognizer2 *recognizer2 = NULL; IActivationFactory *factory = NULL; IInspectable *inspectable = NULL;
- IClosable *closable = NULL; ILanguage *language = NULL; IAsyncInfo *info = NULL;
- struct compilation_handler compilation_handler, compilation_handler2, compilation_handler3; struct completed_event_handler completed_handler; struct recognition_result_handler result_handler;
- struct compilation_handler compilation_handler;
- struct compilation_handler compilation_handler2;
- struct async_operation_block_param block_param; SpeechRecognitionResultStatus result_status; EventRegistrationToken token = { .value = 0 }; AsyncStatus async_status; HSTRING hstr, hstr_lang;
- HANDLE blocked_thread; HRESULT hr; UINT32 id; LONG ref;
@@ -918,11 +937,16 @@ static void test_SpeechRecognizer(void) hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer2, (void **)&recognizer2); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
check_interface(inspectable, &IID_IClosable, TRUE);
hr = ISpeechRecognizer2_get_ContinuousRecognitionSession(recognizer2, &session); ok(hr == S_OK, "ISpeechRecognizer2_get_ContinuousRecognitionSession failed, hr %#lx.\n", hr); check_refcount(session, 2); check_refcount(inspectable, 3);
ref = ISpeechRecognizer2_Release(recognizer2);
ok(ref == 2, "Got unexpected ref %lu.\n", ref);
hr = ISpeechContinuousRecognitionSession_add_Completed(session, NULL, &token); ok(hr == E_INVALIDARG, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
@@ -947,6 +971,9 @@ static void test_SpeechRecognizer(void) hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr);
ref = ISpeechContinuousRecognitionSession_Release(session);
ok(ref == 1, "Got unexpected ref %lu.\n", ref);
hr = ISpeechRecognizer_get_Constraints(recognizer, &constraints); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_get_Constraints failed, hr %#lx.\n", hr);
@@ -1078,22 +1105,62 @@ static void test_SpeechRecognizer(void)
ref = IAsyncInfo_Release(info); todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
-skip_operation: ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
ok(!ref, "Got unexpected ref %lu.\n", ref);
todo_wine ok(!ref, "Got unexpected ref %lu.\n", ref);
ref = ISpeechContinuousRecognitionSession_Release(session);
ok(ref == 1, "Got unexpected ref %lu.\n", ref);
ref = ISpeechRecognizer_Release(recognizer);
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
hr = IInspectable_QueryInterface(inspectable, &IID_IClosable, (void **)&closable);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ref = IInspectable_Release(inspectable);
todo_wine ok(!ref, "Got unexpected ref %lu.\n", ref);
ref = IClosable_Release(closable);
ok(ref == 3, "Got unexpected ref %lu.\n", ref);
/* Test if AsyncInfo_Close waits for the handler to finish. */
hr = RoActivateInstance(hstr, &inspectable);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ref = ISpeechRecognizer2_Release(recognizer2);
ok(ref == 2, "Got unexpected ref %lu.\n", ref);
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer, (void **)&recognizer);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
compilation_handler_create_static(&compilation_handler3);
compilation_handler3.event_block = CreateEventW(NULL, FALSE, FALSE, NULL);
compilation_handler3.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
compilation_handler3.thread_id = GetCurrentThreadId();
todo_wine ok(compilation_handler3.event_finished != NULL, "Finished event wasn't created.\n");
hr = ISpeechRecognizer_CompileConstraintsAsync(recognizer, &operation);
todo_wine ok(hr == S_OK, "ISpeechRecognizer_CompileConstraintsAsync failed, hr %#lx.\n", hr);
block_param.handler = &compilation_handler3.IAsyncHandler_Compilation_iface;
block_param.operation = operation;
blocked_thread = CreateThread(NULL, 0, async_operation_block_thread, &block_param, 0, NULL);
todo_wine ok(!WaitForSingleObject(compilation_handler3.event_finished, 1000), "Wait for event_finished failed.\n");
According to the results, it seems like this one is not big enough? I think thread creation can be unusually slow, and sometimes it's best to create them upfront, and instead use an event to start a test. It complicates things a bit though, maybe just increasing the timeout to 5s would be enough.
todo_wine ok(WaitForSingleObject(blocked_thread, 1000) == WAIT_TIMEOUT, "Wait for block_thread didn't time out.\n");
If you expect a timeout, I think it's best to use lower values, like 100ms, otherwise it's always going to wait 1s and slow down the entire test (1s is not much but they pile up).
todo_wine ok(compilation_handler3.ref == 3, "Got unexpected ref %lu.\n", compilation_handler3.ref);
todo_wine check_refcount(operation, 3);
hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = IAsyncInfo_Close(info); /* If IAsyncInfo_Close would wait for the handler to finish, the test would get stuck here. */
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
SetEvent(compilation_handler3.event_block);
todo_wine ok(!WaitForSingleObject(blocked_thread, 1000), "Wait for block_thread failed.\n");
CloseHandle(blocked_thread);
CloseHandle(compilation_handler3.event_block);
CloseHandle(compilation_handler3.event_finished);
ref = IAsyncInfo_Release(info);
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
+skip_operation:
ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
ok(!ref, "Got unexpected ref %lu.\n", ref); ref = ISpeechRecognizer_Release(recognizer); ok(ref == 1, "Got unexpected ref %lu.\n", ref);
I still don't see why you need another unique compilation_handler variable, but as there's already compilation_handler2 I'm going to ignore it.
Looks good otherwise.