From cdbfa7a3e87530a44a532482d90c5ea23950d1f7 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 1 Mar 2023 23:50:05 +0000 Subject: [PATCH] fastboot: Introduce ParseNetworkSerial unit tests Introduced positive and negative unit tests to cover ParseNetworkSerial logic. Alongside with that move result related stuff to the separate header. Test: atest fastboot_test Test: manually checked basic functionality works fine Bug: 271155012 Change-Id: Icac6053c11b5a36daa64555209555826ea28cc61 Signed-off-by: Dmitrii Merkurev --- fastboot/fastboot.cpp | 33 +++++------------------- fastboot/fastboot.h | 12 +++++++++ fastboot/fastboot_test.cpp | 48 ++++++++++++++++++++++++++++++++++ fastboot/result.h | 53 ++++++++++++++++++++++++++++++++++++++ fastboot/util.h | 18 ------------- 5 files changed, 119 insertions(+), 45 deletions(-) create mode 100644 fastboot/result.h diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 5dac3f5ff..076d8dbc0 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -336,28 +336,7 @@ static int list_devices_callback(usb_ifc_info* info) { return -1; } -struct NetworkSerial { - Socket::Protocol protocol; - std::string address; - int port; -}; - -class ParseNetworkAddressError { - public: - enum Type { WRONG_PREFIX = 1, WRONG_ADDRESS = 2 }; - - ParseNetworkAddressError(Type&& type) : type_(std::forward(type)) {} - - Type value() const { return type_; } - operator Type() const { return value(); } - std::string print() const { return ""; } - - private: - Type type_; -}; - -static Result ParseNetworkSerial( - const std::string& serial) { +Result ParseNetworkSerial(const std::string& serial) { Socket::Protocol protocol; const char* net_address = nullptr; int port = 0; @@ -371,7 +350,7 @@ static Result ParseNetworkSerial( net_address = serial.c_str() + strlen("udp:"); port = udp::kDefaultPort; } else { - return Error(ParseNetworkAddressError::Type::WRONG_PREFIX) + return Error(FastbootError::Type::NETWORK_SERIAL_WRONG_PREFIX) << "protocol prefix ('tcp:' or 'udp:') is missed: " << serial << ". " << "Expected address format:\n" << ":
: (tcp:localhost:5554)"; @@ -380,7 +359,7 @@ static Result ParseNetworkSerial( std::string error; std::string host; if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) { - return Error(ParseNetworkAddressError::Type::WRONG_ADDRESS) + return Error(FastbootError::Type::NETWORK_SERIAL_WRONG_ADDRESS) << "invalid network address '" << net_address << "': " << error; } @@ -399,8 +378,7 @@ static Result ParseNetworkSerial( // object, and the caller should not attempt to delete the returned Transport. static Transport* open_device(const char* local_serial, bool wait_for_device = true, bool announce = true) { - const Result network_serial = - ParseNetworkSerial(local_serial); + const Result network_serial = ParseNetworkSerial(local_serial); Transport* transport = nullptr; while (true) { @@ -417,7 +395,8 @@ static Transport* open_device(const char* local_serial, bool wait_for_device = t if (transport == nullptr && announce) { LOG(ERROR) << "error: " << error; } - } else if (network_serial.error().code() == ParseNetworkAddressError::Type::WRONG_PREFIX) { + } else if (network_serial.error().code() == + FastbootError::Type::NETWORK_SERIAL_WRONG_PREFIX) { // WRONG_PREFIX is special because it happens when user wants to communicate with USB // device transport = usb_open(match_fastboot(local_serial)); diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h index b5fb8c0bf..c1ae6e440 100644 --- a/fastboot/fastboot.h +++ b/fastboot/fastboot.h @@ -31,6 +31,10 @@ #include +#include "result.h" +#include "socket.h" +#include "util.h" + class FastBootTool { public: int Main(int argc, char* argv[]); @@ -48,3 +52,11 @@ void do_for_partitions(const std::string& part, const std::string& slot, std::string find_item(const std::string& item); void reboot_to_userspace_fastboot(); void syntax_error(const char* fmt, ...); + +struct NetworkSerial { + Socket::Protocol protocol; + std::string address; + int port; +}; + +Result ParseNetworkSerial(const std::string& serial); \ No newline at end of file diff --git a/fastboot/fastboot_test.cpp b/fastboot/fastboot_test.cpp index 79f37fd47..1863e9570 100644 --- a/fastboot/fastboot_test.cpp +++ b/fastboot/fastboot_test.cpp @@ -203,6 +203,54 @@ TEST(FastBoot, ParseRequirementLineMalformed) { ParseRequirementLineTestMalformed("require-for-product :"); } +static void ParseNetworkSerialTest(const std::string& description, const std::string& serial, + const std::string& expected_address, + const Socket::Protocol expected_protocol, + const int expected_port) { + const Result parsed = ParseNetworkSerial(serial); + + ASSERT_RESULT_OK(parsed) << description; + + const NetworkSerial network_serial = parsed.value(); + EXPECT_EQ(network_serial.address, expected_address) << description; + EXPECT_EQ(network_serial.protocol, expected_protocol) << description; + EXPECT_EQ(network_serial.port, expected_port) << description; +} + +static void ParseNetworkSerialNegativeTest(const std::string& description, + const std::string& serial, + const FastbootError::Type expected_error) { + const Result parsed = ParseNetworkSerial(serial); + + EXPECT_FALSE(parsed.ok()) << description; + EXPECT_EQ(parsed.error().code(), expected_error) << description; +} + +TEST(FastBoot, ParseNetworkSerial) { + ParseNetworkSerialTest("tcp IPv4 parsed", "tcp:192.168.1.0", "192.168.1.0", + Socket::Protocol::kTcp, 5554); + + ParseNetworkSerialTest("udp IPv4 parsed", "udp:192.168.1.0", "192.168.1.0", + Socket::Protocol::kUdp, 5554); + + ParseNetworkSerialTest("port parsed", "udp:192.168.1.0:9999", "192.168.1.0", + Socket::Protocol::kUdp, 9999); + + ParseNetworkSerialTest("IPv6 parsed", "tcp:2001:db8:3333:4444:5555:6666:7777:8888", + "2001:db8:3333:4444:5555:6666:7777:8888", Socket::Protocol::kTcp, 5554); + + ParseNetworkSerialTest("empty IPv6 parsed", "tcp:::", "::", Socket::Protocol::kTcp, 5554); + + ParseNetworkSerialNegativeTest("wrong prefix", "tcpa:192.168.1.0", + FastbootError::Type::NETWORK_SERIAL_WRONG_PREFIX); + + ParseNetworkSerialNegativeTest("no prefix", "192.168.1.0", + FastbootError::Type::NETWORK_SERIAL_WRONG_PREFIX); + + ParseNetworkSerialNegativeTest("wrong port", "tcp:192.168.1.0:-1", + FastbootError::Type::NETWORK_SERIAL_WRONG_ADDRESS); +} + int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv); android::base::InitLogging(argv); diff --git a/fastboot/result.h b/fastboot/result.h new file mode 100644 index 000000000..dfa5e1067 --- /dev/null +++ b/fastboot/result.h @@ -0,0 +1,53 @@ +/* + * 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 + +#include + +#include "util.h" + +using android::base::ErrnoError; +using android::base::Error; +using android::base::Result; +using android::base::ResultError; + +class FastbootError { + public: + enum Type { NETWORK_SERIAL_WRONG_PREFIX = 1, NETWORK_SERIAL_WRONG_ADDRESS = 2 }; + + FastbootError(Type&& type) : type_(std::forward(type)) {} + + Type value() const { return type_; } + operator Type() const { return value(); } + std::string print() const { return ""; } + + private: + Type type_; +}; + +template +inline T Expect(Result r) { + if (r.ok()) { + return r.value(); + } + + die(r.error().message()); + + return r.value(); +} \ No newline at end of file diff --git a/fastboot/util.h b/fastboot/util.h index 8a79e1303..290d0d5fe 100644 --- a/fastboot/util.h +++ b/fastboot/util.h @@ -6,29 +6,11 @@ #include #include -#include -#include #include #include #include #include -using android::base::ErrnoError; -using android::base::Error; -using android::base::Result; -using android::base::ResultError; - -template -inline T Expect(Result r) { - if (r.ok()) { - return r.value(); - } - - LOG(FATAL) << r.error().message(); - - return r.value(); -} - using SparsePtr = std::unique_ptr; /* util stuff */