From 80882284b4f0b87a1dfd0829d2baf2fc7c253573 Mon Sep 17 00:00:00 2001 From: MuHong Byun Date: Wed, 30 Jun 2021 12:21:19 +0900 Subject: [PATCH] Introduce mock_engine for unittest * copied from linux port ('/shell/platform/linux/testing/mock_engine.cc') Signed-off-by: MuHong Byun --- shell/platform/common/BUILD.gn | 3 +- shell/platform/tizen/BUILD.gn | 16 +- .../tizen/flutter_tizen_engine_test.cc | 13 - shell/platform/tizen/testing/mock_engine.cc | 332 ++++++++++++++++++ 4 files changed, 344 insertions(+), 20 deletions(-) create mode 100644 shell/platform/tizen/testing/mock_engine.cc diff --git a/shell/platform/common/BUILD.gn b/shell/platform/common/BUILD.gn index 3183663bae18a..8ec0a8466d6e1 100644 --- a/shell/platform/common/BUILD.gn +++ b/shell/platform/common/BUILD.gn @@ -114,7 +114,7 @@ source_set("common_cpp") { "//flutter/shell/platform/common/client_wrapper:client_wrapper", ] - if (!build_tizen_shell || enable_desktop_embeddings) { + if (!build_tizen_shell) { deps += [ "//flutter/shell/platform/embedder:embedder_as_internal_library" ] } @@ -182,6 +182,7 @@ if (enable_unittests) { ":common_cpp_switches", "//flutter/shell/platform/common/client_wrapper:client_wrapper", "//flutter/shell/platform/common/client_wrapper:client_wrapper_library_stubs", + "//flutter/shell/platform/embedder:embedder_as_internal_library", "//flutter/testing", ] diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 7393338b33762..95a11eb2a6a5f 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -195,6 +195,10 @@ template("embedder_for_profile") { "//flutter/shell/platform/common/client_wrapper:client_wrapper", "//third_party/rapidjson", ] + if (enable_desktop_embeddings) { + deps += + [ "//flutter/shell/platform/embedder:embedder_as_internal_library" ] + } } } @@ -224,8 +228,11 @@ executable("flutter_tizen_unittests") { testonly = true public = _public_headers sources = _flutter_tizen_source - sources += [ "tizen_renderer_evas_gl.cc" ] - sources += [ "flutter_tizen_engine_test.cc" ] + sources += [ + "flutter_tizen_engine_test.cc", + "testing/mock_engine.cc", + "tizen_renderer_evas_gl.cc", + ] libs = _libs_minimum libs += [ "ecore_evas", @@ -244,10 +251,7 @@ executable("flutter_tizen_unittests") { ":tizen_rootstrap_include_dirs", "//flutter/shell/platform/common:desktop_library_implementation", ] - public_deps = [ - ":flutter_engine", - "//third_party/googletest:gtest", - ] + public_deps = [ "//third_party/googletest:gtest" ] deps = [ ":flutter_tizen_fixtures", "//flutter/runtime:libdart", diff --git a/shell/platform/tizen/flutter_tizen_engine_test.cc b/shell/platform/tizen/flutter_tizen_engine_test.cc index 4d192969892c2..9efad9014b1f4 100644 --- a/shell/platform/tizen/flutter_tizen_engine_test.cc +++ b/shell/platform/tizen/flutter_tizen_engine_test.cc @@ -79,8 +79,6 @@ class FlutterTizenEngineTest : public testing::Test { TEST_F(FlutterTizenEngineTest, Run) { EXPECT_TRUE(engine_ != nullptr); EXPECT_TRUE(engine_->RunEngine(engine_prop)); - // TODO : FIXME - std::this_thread::sleep_for(1s); EXPECT_TRUE(true); } @@ -88,30 +86,19 @@ TEST_F(FlutterTizenEngineTest, Run) { TEST_F(FlutterTizenEngineTest, DISABLED_Run_Twice) { EXPECT_TRUE(engine_ != nullptr); EXPECT_TRUE(engine_->RunEngine(engine_prop)); - // TODO : FIXME - std::this_thread::sleep_for(1s); - EXPECT_FALSE(engine_->RunEngine(engine_prop)); - std::this_thread::sleep_for(1s); - EXPECT_TRUE(true); } TEST_F(FlutterTizenEngineTest, Stop) { EXPECT_TRUE(engine_ != nullptr); EXPECT_TRUE(engine_->RunEngine(engine_prop)); - // TODO : FIXME - std::this_thread::sleep_for(1s); - EXPECT_TRUE(engine_->StopEngine()); } TEST_F(FlutterTizenEngineTest, Stop_Twice) { EXPECT_TRUE(engine_ != nullptr); EXPECT_TRUE(engine_->RunEngine(engine_prop)); - // TODO : FIXME - std::this_thread::sleep_for(1s); - EXPECT_TRUE(engine_->StopEngine()); EXPECT_FALSE(engine_->StopEngine()); } diff --git a/shell/platform/tizen/testing/mock_engine.cc b/shell/platform/tizen/testing/mock_engine.cc new file mode 100644 index 0000000000000..29ed124a0a689 --- /dev/null +++ b/shell/platform/tizen/testing/mock_engine.cc @@ -0,0 +1,332 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include + +#include "flutter/shell/platform/embedder/embedder.h" +#include "gtest/gtest.h" + +const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1; + +struct _FlutterEngine { + bool running; + FlutterPlatformMessageCallback platform_message_callback; + FlutterTaskRunnerPostTaskCallback platform_post_task_callback; + void* user_data; + + _FlutterEngine(FlutterPlatformMessageCallback platform_message_callback, + FlutterTaskRunnerPostTaskCallback platform_post_task_callback, + void* user_data) + : running(false), + platform_message_callback(platform_message_callback), + platform_post_task_callback(platform_post_task_callback), + user_data(user_data) {} +}; + +struct _FlutterPlatformMessageResponseHandle { + FlutterDataCallback data_callback; + void* user_data; + std::string channel; + bool released; + + // Constructor for a response handle generated by the engine. + explicit _FlutterPlatformMessageResponseHandle(std::string channel) + : data_callback(nullptr), + user_data(nullptr), + channel(channel), + released(false) {} + + // Constructor for a response handle generated by the shell. + _FlutterPlatformMessageResponseHandle(FlutterDataCallback data_callback, + void* user_data) + : data_callback(data_callback), user_data(user_data), released(false) {} +}; + +struct _FlutterTaskRunner { + uint64_t task; + std::string channel; + const FlutterPlatformMessageResponseHandle* response_handle; + uint8_t* message; + size_t message_size; + + _FlutterTaskRunner( + uint64_t task, + const std::string& channel, + const FlutterPlatformMessageResponseHandle* response_handle, + const uint8_t* message, + size_t message_size) + : task(task), + channel(channel), + response_handle(response_handle), + message_size(message_size) { + if (message_size > 0) { + this->message = static_cast(malloc(message_size)); + memcpy(this->message, message, message_size); + } else { + this->message = nullptr; + } + } + ~_FlutterTaskRunner() { + if (response_handle != nullptr) { + EXPECT_TRUE(response_handle->released); + delete response_handle; + } + free(message); + } +}; + +// Send a message from the engine. +static void send_message(FLUTTER_API_SYMBOL(FlutterEngine) engine, + const std::string& channel, + const uint8_t* message, + size_t message_size) { + FlutterTask task; + task.runner = + new _FlutterTaskRunner(1234, channel, nullptr, message, message_size); + task.task = task.runner->task; + engine->platform_post_task_callback(task, 0, engine->user_data); +} + +FlutterEngineResult FlutterEngineCreateAOTData( + const FlutterEngineAOTDataSource* source, + FlutterEngineAOTData* data_out) { + *data_out = nullptr; + return kSuccess; +} + +FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineInitialize(size_t version, + const FlutterRendererConfig* config, + const FlutterProjectArgs* args, + void* user_data, + FLUTTER_API_SYMBOL(FlutterEngine) * + engine_out) { + EXPECT_NE(config, nullptr); + + EXPECT_NE(args, nullptr); + EXPECT_NE(args->platform_message_callback, nullptr); + EXPECT_NE(args->custom_task_runners, nullptr); + EXPECT_NE(args->custom_task_runners->platform_task_runner, nullptr); + EXPECT_NE(args->custom_task_runners->platform_task_runner->post_task_callback, + nullptr); + EXPECT_NE(user_data, nullptr); + + *engine_out = new _FlutterEngine( + args->platform_message_callback, + args->custom_task_runners->platform_task_runner->post_task_callback, + user_data); + return kSuccess; +} + +FlutterEngineResult FlutterEngineRunInitialized( + FLUTTER_API_SYMBOL(FlutterEngine) engine) { + engine->running = true; + return kSuccess; +} + +FlutterEngineResult FlutterEngineRun(size_t version, + const FlutterRendererConfig* config, + const FlutterProjectArgs* args, + void* user_data, + FLUTTER_API_SYMBOL(FlutterEngine) * + engine_out) { + EXPECT_NE(config, nullptr); + EXPECT_NE(args, nullptr); + EXPECT_NE(user_data, nullptr); + EXPECT_NE(engine_out, nullptr); + + FlutterEngineResult result = + FlutterEngineInitialize(version, config, args, user_data, engine_out); + if (result != kSuccess) { + return result; + } + return FlutterEngineRunInitialized(*engine_out); +} + +FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) + engine) { + delete engine; + return kSuccess; +} + +FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine) + engine) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineSendWindowMetricsEvent( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterWindowMetricsEvent* event) { + EXPECT_TRUE(engine->running); + return kSuccess; +} + +FlutterEngineResult FlutterEngineSendPointerEvent( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPointerEvent* events, + size_t events_count) { + return kSuccess; +} + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendPlatformMessage( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPlatformMessage* message) { + EXPECT_TRUE(engine->running); + return kSuccess; +} + +FlutterEngineResult FlutterPlatformMessageCreateResponseHandle( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterDataCallback data_callback, + void* user_data, + FlutterPlatformMessageResponseHandle** response_out) { + EXPECT_TRUE(engine->running); + EXPECT_NE(data_callback, nullptr); + EXPECT_NE(user_data, nullptr); + + _FlutterPlatformMessageResponseHandle* handle = + new _FlutterPlatformMessageResponseHandle(data_callback, user_data); + + *response_out = handle; + return kSuccess; +} + +FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterPlatformMessageResponseHandle* response) { + EXPECT_NE(engine, nullptr); + EXPECT_NE(response, nullptr); + + EXPECT_TRUE(engine->running); + + EXPECT_FALSE(response->released); + response->released = true; + + return kSuccess; +} + +FlutterEngineResult FlutterEngineSendPlatformMessageResponse( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPlatformMessageResponseHandle* handle, + const uint8_t* data, + size_t data_length) { + EXPECT_NE(engine, nullptr); + EXPECT_NE(handle, nullptr); + + EXPECT_TRUE(engine->running); + + // Send a message so the shell can check the responses received. + if (handle->channel != "test/responses") { + send_message(engine, "test/responses", data, data_length); + } + + EXPECT_FALSE(handle->released); + + delete handle; + + return kSuccess; +} + +FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine) + engine, + const FlutterTask* task) { + EXPECT_NE(engine, nullptr); + EXPECT_NE(task, nullptr); + EXPECT_NE(task->runner, nullptr); + + FlutterTaskRunner runner = task->runner; + EXPECT_NE(runner, nullptr); + const FlutterPlatformMessageResponseHandle* response_handle = + runner->response_handle; + if (response_handle != nullptr) { + EXPECT_NE(response_handle->data_callback, nullptr); + response_handle->data_callback(runner->message, runner->message_size, + response_handle->user_data); + } else { + _FlutterPlatformMessageResponseHandle* handle = + new _FlutterPlatformMessageResponseHandle(runner->channel); + + FlutterPlatformMessage message; + message.struct_size = sizeof(FlutterPlatformMessage); + message.channel = runner->channel.c_str(); + message.message = runner->message; + message.message_size = runner->message_size; + message.response_handle = handle; + engine->platform_message_callback(&message, engine->user_data); + } + + delete runner; + + return kSuccess; +} + +bool FlutterEngineRunsAOTCompiledDartCode() { + return false; +} + +FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine) + engine, + const FlutterLocale** locales, + size_t locales_count) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineUpdateSemanticsEnabled( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + bool enabled) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineDispatchSemanticsAction( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + uint64_t id, + FlutterSemanticsAction action, + const uint8_t* data, + size_t data_length) { + return kSuccess; +} + +uint64_t FlutterEngineGetCurrentTime() { + return 0; +} + +FlutterEngineResult FlutterEngineGetProcAddresses( + FlutterEngineProcTable* table) { + if (!table) { + return kInvalidArguments; + } + + FlutterEngineProcTable empty_table = {}; + *table = empty_table; + + table->CreateAOTData = &FlutterEngineCreateAOTData; + table->CollectAOTData = &FlutterEngineCollectAOTData; + table->Run = &FlutterEngineRun; + table->Shutdown = &FlutterEngineShutdown; + table->Initialize = &FlutterEngineInitialize; + table->Deinitialize = &FlutterEngineDeinitialize; + table->RunInitialized = &FlutterEngineRunInitialized; + table->SendWindowMetricsEvent = &FlutterEngineSendWindowMetricsEvent; + table->SendPointerEvent = &FlutterEngineSendPointerEvent; + table->SendPlatformMessage = &FlutterEngineSendPlatformMessage; + table->PlatformMessageCreateResponseHandle = + &FlutterPlatformMessageCreateResponseHandle; + table->PlatformMessageReleaseResponseHandle = + &FlutterPlatformMessageReleaseResponseHandle; + table->SendPlatformMessageResponse = + &FlutterEngineSendPlatformMessageResponse; + table->RunTask = &FlutterEngineRunTask; + table->UpdateLocales = &FlutterEngineUpdateLocales; + table->UpdateSemanticsEnabled = &FlutterEngineUpdateSemanticsEnabled; + table->DispatchSemanticsAction = &FlutterEngineDispatchSemanticsAction; + table->RunsAOTCompiledDartCode = &FlutterEngineRunsAOTCompiledDartCode; + + return kSuccess; +}