diff --git a/src/developer/feedback_agent/tests/BUILD.gn b/src/developer/feedback_agent/tests/BUILD.gn index d88ce8128a07950ba69c8eca21a5a0916796dc6e..112df8d83f9480d4c2e95f9267764296a5bacaf5 100644 --- a/src/developer/feedback_agent/tests/BUILD.gn +++ b/src/developer/feedback_agent/tests/BUILD.gn @@ -47,6 +47,10 @@ executable("unittest") { sources = [ "feedback_agent_unittest.cc", + "stub_log_listener.cc", + "stub_log_listener.h", + "stub_scenic.cc", + "stub_scenic.h", ] deps = [ diff --git a/src/developer/feedback_agent/tests/feedback_agent_unittest.cc b/src/developer/feedback_agent/tests/feedback_agent_unittest.cc index 846fa6307c10cf26953987174ef2cb42009b8f69..ba7c3f241bead931853301c57e4a056eb9e1274d 100644 --- a/src/developer/feedback_agent/tests/feedback_agent_unittest.cc +++ b/src/developer/feedback_agent/tests/feedback_agent_unittest.cc @@ -5,13 +5,7 @@ #include "src/developer/feedback_agent/feedback_agent.h" #include <fuchsia/feedback/cpp/fidl.h> -#include <fuchsia/images/cpp/fidl.h> -#include <fuchsia/logger/cpp/fidl.h> #include <fuchsia/math/cpp/fidl.h> -#include <fuchsia/ui/scenic/cpp/fidl.h> -#include <lib/fidl/cpp/binding_set.h> -#include <lib/fidl/cpp/interface_handle.h> -#include <lib/fidl/cpp/interface_request.h> #include <lib/fostr/fidl/fuchsia/math/formatting.h> #include <lib/fostr/fidl/fuchsia/mem/formatting.h> #include <lib/fostr/indent.h> @@ -23,15 +17,14 @@ #include <lib/sys/cpp/testing/service_directory_provider.h> #include <lib/syslog/cpp/logger.h> #include <lib/zx/time.h> -#include <lib/zx/vmo.h> -#include <stdint.h> #include <zircon/errors.h> #include <memory> #include <ostream> #include <vector> -#include "src/lib/files/file.h" +#include "src/developer/feedback_agent/tests/stub_log_listener.h" +#include "src/developer/feedback_agent/tests/stub_scenic.h" #include "src/lib/fxl/logging.h" #include "src/lib/fxl/strings/string_printf.h" #include "third_party/googletest/googlemock/include/gmock/gmock.h" @@ -41,79 +34,9 @@ namespace fuchsia { namespace feedback { namespace { -using fuchsia::ui::scenic::ScreenshotData; - constexpr bool kSuccess = true; constexpr bool kFailure = false; -constexpr zx_time_t kSyslogBaseTimestamp = ZX_SEC(15604); -constexpr uint64_t kSyslogProcessId = 7559; -constexpr uint64_t kSyslogThreadId = 7687; - -// Returns an empty screenshot, still needed when Scenic::TakeScreenshot() -// returns false as the FIDL ScreenshotData field is not marked optional in -// fuchsia.ui.scenic.Scenic.TakeScreenshot. -ScreenshotData CreateEmptyScreenshot() { - ScreenshotData screenshot; - FXL_CHECK(zx::vmo::create(0, 0u, &screenshot.data.vmo) == ZX_OK); - return screenshot; -} - -struct RGBA { - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; -}; - -// Returns an 8-bit BGRA image of a |image_dim_in_px| x |image_dim_in_px| -// checkerboard, where each white/black region is a 10x10 pixel square. -ScreenshotData CreateCheckerboardScreenshot(const size_t image_dim_in_px) { - const size_t height = image_dim_in_px; - const size_t width = image_dim_in_px; - const size_t block_size = 10; - const uint8_t black = 0; - const uint8_t white = 0xff; - - const size_t size_in_bytes = image_dim_in_px * image_dim_in_px * sizeof(RGBA); - auto ptr = std::make_unique<uint8_t[]>(size_in_bytes); - RGBA* pixels = reinterpret_cast<RGBA*>(ptr.get()); - - // We go pixel by pixel, row by row. |y| tracks the row and |x| the column. - // - // We compute in which |block_size| x |block_size| block the pixel is to - // determine the color (black or white). |block_y| tracks the "block" row and - // |block_x| the "block" column. - for (size_t y = 0; y < height; ++y) { - size_t block_y = y / block_size; - for (size_t x = 0; x < width; ++x) { - size_t block_x = x / block_size; - uint8_t block_color = (block_x + block_y) % 2 ? black : white; - size_t index = y * width + x; - auto& p = pixels[index]; - p.r = p.g = p.b = block_color; - p.a = 255; - } - } - - ScreenshotData screenshot; - FXL_CHECK(zx::vmo::create(size_in_bytes, 0u, &screenshot.data.vmo) == ZX_OK); - FXL_CHECK(screenshot.data.vmo.write(ptr.get(), 0u, size_in_bytes) == ZX_OK); - screenshot.data.size = size_in_bytes; - screenshot.info.height = image_dim_in_px; - screenshot.info.width = image_dim_in_px; - screenshot.info.stride = image_dim_in_px * 4u /*4 bytes per pixel*/; - screenshot.info.pixel_format = fuchsia::images::PixelFormat::BGRA_8; - return screenshot; -} - -// Returns an empty screenshot with a pixel format different from BGRA-8. -ScreenshotData CreateNonBGRA8Screenshot() { - ScreenshotData screenshot = CreateEmptyScreenshot(); - screenshot.info.pixel_format = fuchsia::images::PixelFormat::YUY2; - return screenshot; -} - // Returns a Screenshot with the right dimensions, no image. std::unique_ptr<Screenshot> MakeUniqueScreenshot(const size_t image_dim_in_px) { std::unique_ptr<Screenshot> screenshot = std::make_unique<Screenshot>(); @@ -122,15 +45,6 @@ std::unique_ptr<Screenshot> MakeUniqueScreenshot(const size_t image_dim_in_px) { return screenshot; } -// Represents arguments for Scenic::TakeScreenshot(). -struct TakeScreenshotResponse { - ScreenshotData screenshot; - bool success; - - TakeScreenshotResponse(ScreenshotData data, bool success) - : screenshot(std::move(data)), success(success){}; -}; - // Represents arguments for DataProvider::GetScreenshotCallback. struct GetScreenshotResponse { std::unique_ptr<Screenshot> screenshot; @@ -233,84 +147,6 @@ MATCHER_P2(MatchesAttachment, expected_key, expected_value, return DoAttachmentMatch(arg, expected_key, expected_value, result_listener); } -// Stub Scenic service to return canned responses to Scenic::TakeScreenshot(). -class StubScenic : public fuchsia::ui::scenic::Scenic { - public: - // Returns a request handler for binding to this stub service. - fidl::InterfaceRequestHandler<fuchsia::ui::scenic::Scenic> GetHandler() { - return bindings_.GetHandler(this); - } - - // Scenic methods. - void CreateSession( - fidl::InterfaceRequest<fuchsia::ui::scenic::Session> session, - fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener) - override { - FXL_NOTIMPLEMENTED(); - } - void GetDisplayInfo(GetDisplayInfoCallback callback) override { - FXL_NOTIMPLEMENTED(); - } - void GetDisplayOwnershipEvent( - GetDisplayOwnershipEventCallback callback) override { - FXL_NOTIMPLEMENTED(); - } - void TakeScreenshot(TakeScreenshotCallback callback) override { - FXL_CHECK(!take_screenshot_responses_.empty()) - << "You need to set up Scenic::TakeScreenshot() responses before " - "testing GetScreenshot() using set_scenic_responses()"; - TakeScreenshotResponse response = std::move(take_screenshot_responses_[0]); - take_screenshot_responses_.erase(take_screenshot_responses_.begin()); - callback(std::move(response.screenshot), response.success); - } - - // Stub injection and verification methods. - void set_take_screenshot_responses( - std::vector<TakeScreenshotResponse> responses) { - take_screenshot_responses_ = std::move(responses); - } - const std::vector<TakeScreenshotResponse>& take_screenshot_responses() const { - return take_screenshot_responses_; - } - - private: - fidl::BindingSet<fuchsia::ui::scenic::Scenic> bindings_; - std::vector<TakeScreenshotResponse> take_screenshot_responses_; -}; - -// Stub Log service to return canned responses to Log::DumpLogs(). -class StubLogger : public fuchsia::logger::Log { - public: - // Returns a request handler for binding to this stub service. - fidl::InterfaceRequestHandler<fuchsia::logger::Log> GetHandler() { - return bindings_.GetHandler(this); - } - - // fuchsia::logger::Log methods. - void Listen( - fidl::InterfaceHandle<fuchsia::logger::LogListener> log_listener, - std::unique_ptr<fuchsia::logger::LogFilterOptions> options) override { - FXL_NOTIMPLEMENTED(); - } - void DumpLogs( - fidl::InterfaceHandle<fuchsia::logger::LogListener> log_listener, - std::unique_ptr<fuchsia::logger::LogFilterOptions> options) override { - fuchsia::logger::LogListenerPtr log_listener_ptr = log_listener.Bind(); - FXL_CHECK(log_listener_ptr.is_bound()); - log_listener_ptr->LogMany(messages_); - log_listener_ptr->Done(); - } - - // Stub injection methods. - void set_messages(const std::vector<fuchsia::logger::LogMessage>& messages) { - messages_ = messages; - } - - private: - fidl::BindingSet<fuchsia::logger::Log> bindings_; - std::vector<fuchsia::logger::LogMessage> messages_; -}; - // Unit-tests the implementation of the fuchsia.feedback.DataProvider FIDL // interface. // @@ -480,20 +316,6 @@ TEST_F(FeedbackAgentTest, GetScreenshot_ParallelRequests) { } } -fuchsia::logger::LogMessage BuildLogMessage( - const int32_t severity, const std::string& text, - const zx_time_t timestamp_offset, - const std::vector<std::string>& tags = {}) { - fuchsia::logger::LogMessage msg{}; - msg.time = kSyslogBaseTimestamp + timestamp_offset; - msg.pid = kSyslogProcessId; - msg.tid = kSyslogThreadId; - msg.tags = tags; - msg.severity = severity; - msg.msg = text; - return msg; -} - TEST_F(FeedbackAgentTest, GetData_SmokeTest) { set_logger_messages({ BuildLogMessage(0 /*INFO*/, "line 1", 0), diff --git a/src/developer/feedback_agent/tests/stub_log_listener.cc b/src/developer/feedback_agent/tests/stub_log_listener.cc new file mode 100644 index 0000000000000000000000000000000000000000..033293ddac54750c5f8fe08a23491494e759f634 --- /dev/null +++ b/src/developer/feedback_agent/tests/stub_log_listener.cc @@ -0,0 +1,46 @@ +// Copyright 2019 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/developer/feedback_agent/tests/stub_log_listener.h" + +#include <fuchsia/logger/cpp/fidl.h> +#include <lib/zx/time.h> +#include <stdint.h> + +#include "src/lib/fxl/logging.h" + +namespace fuchsia { +namespace feedback { +namespace { + +constexpr zx_time_t kLogMessageBaseTimestamp = ZX_SEC(15604); +constexpr uint64_t kLogMessageProcessId = 7559; +constexpr uint64_t kLogMessageThreadId = 7687; + +} // namespace + +fuchsia::logger::LogMessage BuildLogMessage( + const int32_t severity, const std::string& text, + const zx_time_t timestamp_offset, const std::vector<std::string>& tags) { + fuchsia::logger::LogMessage msg{}; + msg.time = kLogMessageBaseTimestamp + timestamp_offset; + msg.pid = kLogMessageProcessId; + msg.tid = kLogMessageThreadId; + msg.tags = tags; + msg.severity = severity; + msg.msg = text; + return msg; +} + +void StubLogger::DumpLogs( + fidl::InterfaceHandle<fuchsia::logger::LogListener> log_listener, + std::unique_ptr<fuchsia::logger::LogFilterOptions> options) { + fuchsia::logger::LogListenerPtr log_listener_ptr = log_listener.Bind(); + FXL_CHECK(log_listener_ptr.is_bound()); + log_listener_ptr->LogMany(messages_); + log_listener_ptr->Done(); +} + +} // namespace feedback +} // namespace fuchsia diff --git a/src/developer/feedback_agent/tests/stub_log_listener.h b/src/developer/feedback_agent/tests/stub_log_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..bdc034c791ba24d3e163cd6af865fd09c7265e9c --- /dev/null +++ b/src/developer/feedback_agent/tests/stub_log_listener.h @@ -0,0 +1,55 @@ +// Copyright 2019 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <fuchsia/logger/cpp/fidl.h> +#include <lib/fidl/cpp/binding_set.h> +#include <lib/fidl/cpp/interface_handle.h> +#include <lib/zx/time.h> + +#include <string> +#include <vector> + +#include "src/lib/fxl/logging.h" + +namespace fuchsia { +namespace feedback { + +// Returns a LogMessage with the given severity, message and optional tags. +// The process and thread ids are constants. The timestamp is a constant plus +// the provided offset. +fuchsia::logger::LogMessage BuildLogMessage( + const int32_t severity, const std::string& text, + const zx_time_t timestamp_offset, + const std::vector<std::string>& tags = {}); + +// Stub Log service to return canned responses to Log::DumpLogs(). +class StubLogger : public fuchsia::logger::Log { + public: + // Returns a request handler for binding to this stub service. + fidl::InterfaceRequestHandler<fuchsia::logger::Log> GetHandler() { + return bindings_.GetHandler(this); + } + + // fuchsia::logger::Log methods. + void Listen( + fidl::InterfaceHandle<fuchsia::logger::LogListener> log_listener, + std::unique_ptr<fuchsia::logger::LogFilterOptions> options) override { + FXL_NOTIMPLEMENTED(); + } + void DumpLogs( + fidl::InterfaceHandle<fuchsia::logger::LogListener> log_listener, + std::unique_ptr<fuchsia::logger::LogFilterOptions> options) override; + + // Stub injection methods. + void set_messages(const std::vector<fuchsia::logger::LogMessage>& messages) { + messages_ = messages; + } + + private: + fidl::BindingSet<fuchsia::logger::Log> bindings_; + std::vector<fuchsia::logger::LogMessage> messages_; +}; + +} // namespace feedback +} // namespace fuchsia diff --git a/src/developer/feedback_agent/tests/stub_scenic.cc b/src/developer/feedback_agent/tests/stub_scenic.cc new file mode 100644 index 0000000000000000000000000000000000000000..6a9a3216622af95e6457ecd8aaa26592b65785cb --- /dev/null +++ b/src/developer/feedback_agent/tests/stub_scenic.cc @@ -0,0 +1,89 @@ +// Copyright 2019 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/developer/feedback_agent/tests/stub_scenic.h" + +#include <fuchsia/images/cpp/fidl.h> +#include <lib/zx/vmo.h> +#include <stdint.h> + +#include "src/lib/fxl/logging.h" + +namespace fuchsia { +namespace feedback { +namespace { + +using fuchsia::ui::scenic::ScreenshotData; + +struct RGBA { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +}; + +} // namespace + +ScreenshotData CreateEmptyScreenshot() { + ScreenshotData screenshot; + FXL_CHECK(zx::vmo::create(0, 0u, &screenshot.data.vmo) == ZX_OK); + return screenshot; +} + +ScreenshotData CreateCheckerboardScreenshot(const size_t image_dim_in_px) { + const size_t height = image_dim_in_px; + const size_t width = image_dim_in_px; + const size_t block_size = 10; + const uint8_t black = 0; + const uint8_t white = 0xff; + + const size_t size_in_bytes = image_dim_in_px * image_dim_in_px * sizeof(RGBA); + auto ptr = std::make_unique<uint8_t[]>(size_in_bytes); + RGBA* pixels = reinterpret_cast<RGBA*>(ptr.get()); + + // We go pixel by pixel, row by row. |y| tracks the row and |x| the column. + // + // We compute in which |block_size| x |block_size| block the pixel is to + // determine the color (black or white). |block_y| tracks the "block" row and + // |block_x| the "block" column. + for (size_t y = 0; y < height; ++y) { + size_t block_y = y / block_size; + for (size_t x = 0; x < width; ++x) { + size_t block_x = x / block_size; + uint8_t block_color = (block_x + block_y) % 2 ? black : white; + size_t index = y * width + x; + auto& p = pixels[index]; + p.r = p.g = p.b = block_color; + p.a = 255; + } + } + + ScreenshotData screenshot; + FXL_CHECK(zx::vmo::create(size_in_bytes, 0u, &screenshot.data.vmo) == ZX_OK); + FXL_CHECK(screenshot.data.vmo.write(ptr.get(), 0u, size_in_bytes) == ZX_OK); + screenshot.data.size = size_in_bytes; + screenshot.info.height = image_dim_in_px; + screenshot.info.width = image_dim_in_px; + screenshot.info.stride = image_dim_in_px * 4u /*4 bytes per pixel*/; + screenshot.info.pixel_format = fuchsia::images::PixelFormat::BGRA_8; + return screenshot; +} + +ScreenshotData CreateNonBGRA8Screenshot() { + ScreenshotData screenshot = CreateEmptyScreenshot(); + screenshot.info.pixel_format = fuchsia::images::PixelFormat::YUY2; + return screenshot; +} + +void StubScenic::TakeScreenshot(TakeScreenshotCallback callback) { + FXL_CHECK(!take_screenshot_responses_.empty()) + << "You need to set up Scenic::TakeScreenshot() responses before " + "testing GetScreenshot() using set_scenic_responses()"; + TakeScreenshotResponse response = std::move(take_screenshot_responses_[0]); + take_screenshot_responses_.erase(take_screenshot_responses_.begin()); + callback(std::move(response.screenshot), response.success); +} + +} // namespace feedback +} // namespace fuchsia diff --git a/src/developer/feedback_agent/tests/stub_scenic.h b/src/developer/feedback_agent/tests/stub_scenic.h new file mode 100644 index 0000000000000000000000000000000000000000..72f8e5e9efd92c7eae072d73d29abaf2d0278f01 --- /dev/null +++ b/src/developer/feedback_agent/tests/stub_scenic.h @@ -0,0 +1,78 @@ +// Copyright 2019 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <fuchsia/ui/scenic/cpp/fidl.h> +#include <lib/fidl/cpp/binding_set.h> +#include <lib/fidl/cpp/interface_handle.h> +#include <lib/fidl/cpp/interface_request.h> + +#include <vector> + +#include "src/lib/fxl/logging.h" + +namespace fuchsia { +namespace feedback { + +// Returns an empty screenshot, still needed when Scenic::TakeScreenshot() +// returns false as the FIDL ScreenshotData field is not marked optional in +// fuchsia.ui.scenic.Scenic.TakeScreenshot. +fuchsia::ui::scenic::ScreenshotData CreateEmptyScreenshot(); + +// Returns an 8-bit BGRA image of a |image_dim_in_px| x |image_dim_in_px| +// checkerboard, where each white/black region is a 10x10 pixel square. +fuchsia::ui::scenic::ScreenshotData CreateCheckerboardScreenshot( + const size_t image_dim_in_px); + +// Returns an empty screenshot with a pixel format different from BGRA-8. +fuchsia::ui::scenic::ScreenshotData CreateNonBGRA8Screenshot(); + +// Represents arguments for Scenic::TakeScreenshot(). +struct TakeScreenshotResponse { + fuchsia::ui::scenic::ScreenshotData screenshot; + bool success; + + TakeScreenshotResponse(fuchsia::ui::scenic::ScreenshotData data, bool success) + : screenshot(std::move(data)), success(success){}; +}; + +// Stub Scenic service to return canned responses to Scenic::TakeScreenshot(). +class StubScenic : public fuchsia::ui::scenic::Scenic { + public: + // Returns a request handler for binding to this stub service. + fidl::InterfaceRequestHandler<fuchsia::ui::scenic::Scenic> GetHandler() { + return bindings_.GetHandler(this); + } + + // fuchsia::ui::scenic::Scenic methods. + void CreateSession( + fidl::InterfaceRequest<fuchsia::ui::scenic::Session> session, + fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener) + override { + FXL_NOTIMPLEMENTED(); + } + void GetDisplayInfo(GetDisplayInfoCallback callback) override { + FXL_NOTIMPLEMENTED(); + } + void GetDisplayOwnershipEvent( + GetDisplayOwnershipEventCallback callback) override { + FXL_NOTIMPLEMENTED(); + } + void TakeScreenshot(TakeScreenshotCallback callback) override; + + // Stub injection and verification methods. + void set_take_screenshot_responses( + std::vector<TakeScreenshotResponse> responses) { + take_screenshot_responses_ = std::move(responses); + } + const std::vector<TakeScreenshotResponse>& take_screenshot_responses() const { + return take_screenshot_responses_; + } + + private: + fidl::BindingSet<fuchsia::ui::scenic::Scenic> bindings_; + std::vector<TakeScreenshotResponse> take_screenshot_responses_; +}; + +} // namespace feedback +} // namespace fuchsia