fastboot: Add a mock transport and some driver tests.
Bug: N/A
Test: fastboot_test
Change-Id: I08d8dfedcc7e9dad9ce418e0f3aaf5ac69a3a2a2
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 76aaf7b..3c110ee 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -375,6 +375,7 @@
defaults: ["fastboot_host_defaults"],
srcs: [
+ "fastboot_driver_test.cpp",
"fastboot_test.cpp",
"socket_mock.cpp",
"socket_test.cpp",
@@ -383,7 +384,10 @@
"udp_test.cpp",
],
- static_libs: ["libfastboot"],
+ static_libs: [
+ "libfastboot",
+ "libgmock",
+ ],
target: {
windows: {
diff --git a/fastboot/fastboot_driver_test.cpp b/fastboot/fastboot_driver_test.cpp
new file mode 100644
index 0000000..e874c3a
--- /dev/null
+++ b/fastboot/fastboot_driver_test.cpp
@@ -0,0 +1,60 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "fastboot_driver.h"
+
+#include <optional>
+
+#include <gtest/gtest.h>
+#include "mock_transport.h"
+
+using namespace ::testing;
+using namespace fastboot;
+
+class DriverTest : public ::testing::Test {
+ protected:
+ InSequence s_;
+};
+
+TEST_F(DriverTest, GetVar) {
+ MockTransport transport;
+ FastBootDriver driver(&transport);
+
+ EXPECT_CALL(transport, Write(_, _))
+ .With(AllArgs(RawData("getvar:version")))
+ .WillOnce(ReturnArg<1>());
+ EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY0.4")));
+
+ std::string output;
+ ASSERT_EQ(driver.GetVar("version", &output), SUCCESS) << driver.Error();
+ ASSERT_EQ(output, "0.4");
+}
+
+TEST_F(DriverTest, InfoMessage) {
+ MockTransport transport;
+ FastBootDriver driver(&transport);
+
+ EXPECT_CALL(transport, Write(_, _))
+ .With(AllArgs(RawData("oem dmesg")))
+ .WillOnce(ReturnArg<1>());
+ EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("INFOthis is an info line")));
+ EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
+
+ std::vector<std::string> info;
+ ASSERT_EQ(driver.RawCommand("oem dmesg", "", nullptr, &info), SUCCESS) << driver.Error();
+ ASSERT_EQ(info.size(), size_t(1));
+ ASSERT_EQ(info[0], "this is an info line");
+}
diff --git a/fastboot/mock_transport.h b/fastboot/mock_transport.h
new file mode 100644
index 0000000..cc3840c
--- /dev/null
+++ b/fastboot/mock_transport.h
@@ -0,0 +1,67 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#pragma once
+
+#include <string.h>
+
+#include <algorithm>
+#include <string_view>
+
+#include <gmock/gmock.h>
+#include "transport.h"
+
+class MockTransport : public Transport {
+ public:
+ MOCK_METHOD(ssize_t, Read, (void* data, size_t len), (override));
+ MOCK_METHOD(ssize_t, Write, (const void* data, size_t len), (override));
+ MOCK_METHOD(int, Close, (), (override));
+ MOCK_METHOD(int, Reset, (), (override));
+};
+
+class RawDataMatcher {
+ public:
+ explicit RawDataMatcher(const char* data) : data_(data) {}
+ explicit RawDataMatcher(std::string_view data) : data_(data) {}
+
+ bool MatchAndExplain(std::tuple<const void*, size_t> args,
+ ::testing::MatchResultListener*) const {
+ const void* expected_data = std::get<0>(args);
+ size_t expected_len = std::get<1>(args);
+ if (expected_len != data_.size()) {
+ return false;
+ }
+ return memcmp(expected_data, data_.data(), expected_len) == 0;
+ }
+ void DescribeTo(std::ostream* os) const { *os << "raw data is"; }
+ void DescribeNegationTo(std::ostream* os) const { *os << "raw data is not"; }
+
+ private:
+ std::string_view data_;
+};
+
+template <typename T>
+static inline ::testing::PolymorphicMatcher<RawDataMatcher> RawData(T data) {
+ return ::testing::MakePolymorphicMatcher(RawDataMatcher(data));
+}
+
+static inline auto CopyData(const char* source) {
+ return [source](void* buffer, size_t size) -> ssize_t {
+ size_t to_copy = std::min(size, strlen(source));
+ memcpy(buffer, source, to_copy);
+ return to_copy;
+ };
+};