From 4bd7da967a3b4371330e90689db8d0d4f76b73c9 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Thu, 23 Mar 2023 11:39:51 -0700 Subject: [PATCH] Add MessageStream fuzzing test PiperOrigin-RevId: 518920458 --- fastpair/message_stream/BUILD | 1 + .../message_stream/message_stream_test.cc | 141 +++++++++++------- 2 files changed, 89 insertions(+), 53 deletions(-) diff --git a/fastpair/message_stream/BUILD b/fastpair/message_stream/BUILD index 7c01b9a7..f0d50841 100644 --- a/fastpair/message_stream/BUILD +++ b/fastpair/message_stream/BUILD @@ -133,6 +133,7 @@ cc_test( "//internal/platform:types", "//internal/platform/implementation:types", "//internal/platform/implementation/g3", # build_cleaner: keep + "//testing/fuzzing:fuzztest", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", diff --git a/fastpair/message_stream/message_stream_test.cc b/fastpair/message_stream/message_stream_test.cc index 8957a11a..63956fd3 100644 --- a/fastpair/message_stream/message_stream_test.cc +++ b/fastpair/message_stream/message_stream_test.cc @@ -15,6 +15,7 @@ #include "fastpair/message_stream/message_stream.h" #include +#include #include #include #include @@ -22,6 +23,7 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "testing/fuzzing/fuzztest.h" #include "absl/status/status.h" #include "absl/strings/escaping.h" #include "absl/time/clock.h" @@ -51,6 +53,57 @@ class MediumEnvironmentStarter { ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } }; +class FakeObserver : public MessageStream::Observer { + public: + void OnConnectionResult(absl::Status result) override { + NEARBY_LOGS(INFO) << "OnConnectionResult " << result; + connection_result_.Set(result); + } + + void OnDisconnected(absl::Status status) override { + NEARBY_LOGS(INFO) << "OnDisconnected " << status; + disconnected_reason_.Set(status); + } + + void OnEnableSilenceMode(bool enable) override { silence_mode_.Set(enable); } + + void OnLogBufferFull() override { log_buffer_full_.Set(true); } + + void OnModelId(int model_id) override { model_id_.Set(model_id); } + + void OnBleAddressUpdated(absl::string_view address) override { + ble_address_updated_.Set(std::string(address)); + } + + void OnBatteryUpdated( + std::vector battery_levels) override { + battery_levels_.Set(battery_levels); + } + + void OnRemainingBatteryTime(absl::Duration duration) override { + remaining_battery_time_.Set(duration); + } + + bool OnRing(uint8_t components, absl::Duration duration) override { + on_ring_event_.Set({components, duration}); + // This allows us to test returning ACK/NACK to the seeker. + return components != 0xAB; + } + Future connection_result_; + Future disconnected_reason_; + Future model_id_; + Future ble_address_updated_; + Future> battery_levels_; + Future remaining_battery_time_; + Future silence_mode_; + Future log_buffer_full_; + struct OnRingData { + uint8_t components; + absl::Duration duration; + }; + Future on_ring_event_; +}; + class MessageStreamTest : public testing::Test { protected: void SetUp() override { @@ -89,59 +142,6 @@ class MessageStreamTest : public testing::Test { FastPairDevice fp_device_{"model id", "ble address", Protocol::kFastPairRetroactivePairing}; - class FakeObserver : public MessageStream::Observer { - public: - void OnConnectionResult(absl::Status result) override { - NEARBY_LOGS(INFO) << "OnConnectionResult " << result; - connection_result_.Set(result); - } - - void OnDisconnected(absl::Status status) override { - NEARBY_LOGS(INFO) << "OnDisconnected " << status; - disconnected_reason_.Set(status); - } - - void OnEnableSilenceMode(bool enable) override { - silence_mode_.Set(enable); - } - - void OnLogBufferFull() override { log_buffer_full_.Set(true); } - - void OnModelId(int model_id) override { model_id_.Set(model_id); } - - void OnBleAddressUpdated(absl::string_view address) override { - ble_address_updated_.Set(std::string(address)); - } - - void OnBatteryUpdated( - std::vector battery_levels) override { - battery_levels_.Set(battery_levels); - } - - void OnRemainingBatteryTime(absl::Duration duration) override { - remaining_battery_time_.Set(duration); - } - - bool OnRing(uint8_t components, absl::Duration duration) override { - on_ring_event_.Set({components, duration}); - // This allows us to test returning ACK/NACK to the seeker. - return components != 0xAB; - } - Future connection_result_; - Future disconnected_reason_; - Future model_id_; - Future ble_address_updated_; - Future> battery_levels_; - Future remaining_battery_time_; - Future silence_mode_; - Future log_buffer_full_; - struct OnRingData { - uint8_t components; - absl::Duration duration; - }; - Future on_ring_event_; - }; - FakeObserver observer_; }; @@ -413,6 +413,41 @@ TEST_F(MessageStreamTest, ReceiveRemainingBatteryTimeHighValue) { absl::Minutes(0xABCD)); } +template +std::vector GetAllEnums(int min_value, int max_value) { + int count = max_value - min_value + 1; + std::vector enums(count); + for (int i = 0; i < count; i++) { + enums[i] = static_cast(min_value + i); + } + return enums; +} + +// MessageGroup received over the wire is an 8-bit number. +auto AnyMessageGroup() { + return fuzztest::ElementOf(GetAllEnums(0, 255)); +} + +// MessageCode received over the wire is an 8-bit number. +auto AnyMessageCode() { + return fuzztest::ElementOf(GetAllEnums(0, 255)); +} + +void HandlesAnyMessage(MessageGroup group, MessageCode code, + absl::string_view payload) { + FastPairDevice fp_device("model id", "ble address", + Protocol::kFastPairRetroactivePairing); + FakeObserver observer; + MessageStream message_stream(fp_device, std::nullopt, observer); + message_stream.OnReceived(Message{.message_group = group, + .message_code = code, + .payload = std::string(payload)}); +} + +FUZZ_TEST(MessageStreamFuzzTest, HandlesAnyMessage) + .WithDomains(AnyMessageGroup(), AnyMessageCode(), + fuzztest::Arbitrary()); + } // namespace } // namespace fastpair } // namespace nearby