xref: /aosp_15_r20/external/cronet/base/fuchsia/system_product_info_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fidl/fuchsia.buildinfo/cpp/fidl.h>
6 #include <fidl/fuchsia.hwinfo/cpp/fidl.h>
7 #include <lib/async/default.h>
8 #include <lib/fidl/cpp/wire/connect_service.h>
9 
10 #include <memory>
11 #include <string>
12 #include <string_view>
13 
14 #include "base/fuchsia/scoped_service_binding.h"
15 #include "base/fuchsia/system_info.h"
16 #include "base/fuchsia/test_component_context_for_process.h"
17 #include "base/functional/bind.h"
18 #include "base/functional/callback_forward.h"
19 #include "base/location.h"
20 #include "base/run_loop.h"
21 #include "base/test/bind.h"
22 #include "base/test/gtest_util.h"
23 #include "base/test/task_environment.h"
24 #include "base/test/test_future.h"
25 #include "base/threading/sequence_bound.h"
26 #include "base/threading/thread.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 
29 namespace base {
30 
31 namespace {
32 
33 class FakeHardwareInfoProduct : public fidl::Server<fuchsia_hwinfo::Product> {
34  public:
FakeHardwareInfoProduct(const std::string_view model,const std::string_view manufacturer,sys::OutgoingDirectory * outgoing_services)35   FakeHardwareInfoProduct(const std::string_view model,
36                           const std::string_view manufacturer,
37                           sys::OutgoingDirectory* outgoing_services)
38       : model_(model),
39         manufacturer_(manufacturer),
40         binding_(outgoing_services, this) {}
41   FakeHardwareInfoProduct(const FakeHardwareInfoProduct&) = delete;
42   FakeHardwareInfoProduct& operator=(const FakeHardwareInfoProduct&) = delete;
43   ~FakeHardwareInfoProduct() override = default;
44 
GetInfo(GetInfoCompleter::Sync & completer)45   void GetInfo(GetInfoCompleter::Sync& completer) override {
46     completer.Reply(fuchsia_hwinfo::ProductInfo{{
47         .model = model_,
48         .manufacturer = manufacturer_,
49     }});
50   }
51 
52  private:
53   std::string model_;
54   std::string manufacturer_;
55   ScopedNaturalServiceBinding<fuchsia_hwinfo::Product> binding_;
56 };
57 
58 }  // namespace
59 
60 // Uses a fake "fuchsia.hwinfo.Product" implementation.
61 // clears the cached ProductInfo to ensure that each test starts with no cached
62 // ProductInfo and that subsequent tests runs do not use fake values.
63 class ProductInfoTest : public testing::Test {
64  protected:
ProductInfoTest()65   ProductInfoTest()
66       : task_environment_(
67             base::test::SingleThreadTaskEnvironment::MainThreadType::IO),
68         thread_("ProductInfo Retrieval Thread") {
69     thread_.StartWithOptions(
70         base::Thread::Options(base::MessagePumpType::IO, 0));
71     ClearCachedSystemInfoForTesting();
72     component_context_.AddService(
73         fidl::DiscoverableProtocolName<fuchsia_buildinfo::Provider>);
74   }
~ProductInfoTest()75   ~ProductInfoTest() override { ClearCachedSystemInfoForTesting(); }
76 
77   // Fetch the product info in a separate thread, while servicing the
78   // FIDL fake implementation on the main thread.
GetProductInfoViaTask()79   fuchsia_hwinfo::ProductInfo GetProductInfoViaTask() {
80     fuchsia_hwinfo::ProductInfo product_info;
81     base::RunLoop run_loop;
82     thread_.task_runner()->PostTaskAndReplyWithResult(
83         FROM_HERE, base::BindOnce(&GetProductInfo),
84         base::BindOnce(
85             [](base::RunLoop& run_loop,
86                fuchsia_hwinfo::ProductInfo& product_info,
87                fuchsia_hwinfo::ProductInfo result) {
88               product_info = std::move(result);
89               run_loop.Quit();
90             },
91             std::ref(run_loop), std::ref(product_info)));
92     run_loop.Run();
93     return product_info;
94   }
95 
96   base::test::SingleThreadTaskEnvironment task_environment_;
97   TestComponentContextForProcess component_context_;
98   base::Thread thread_;
99 };
100 
101 using ProductInfoDeathTest = ProductInfoTest;
102 
TEST_F(ProductInfoTest,GetProductInfoReturnsFakedValues)103 TEST_F(ProductInfoTest, GetProductInfoReturnsFakedValues) {
104   FakeHardwareInfoProduct hwinfo_product_provider(
105       "test.model", "test.manufacturer",
106       component_context_.additional_services());
107 
108   const auto product_info = GetProductInfoViaTask();
109   EXPECT_EQ(product_info.model().value(), "test.model");
110   EXPECT_EQ(product_info.manufacturer().value(), "test.manufacturer");
111 }
112 
TEST_F(ProductInfoTest,SystemServiceReturnsValidValues)113 TEST_F(ProductInfoTest, SystemServiceReturnsValidValues) {
114   component_context_.AddService(
115       fidl::DiscoverableProtocolName<fuchsia_hwinfo::Product>);
116 
117   const auto product_info = GetProductInfoViaTask();
118   EXPECT_TRUE(product_info.model().has_value());
119   EXPECT_FALSE(product_info.model()->empty());
120 
121   EXPECT_TRUE(product_info.manufacturer().has_value());
122   EXPECT_FALSE(product_info.manufacturer()->empty());
123 }
124 
125 // TODO(crbug.com/101396): Re-enable once all clients
126 // provide this service.
TEST_F(ProductInfoDeathTest,DISABLED_DcheckOnServiceNotPresent)127 TEST_F(ProductInfoDeathTest, DISABLED_DcheckOnServiceNotPresent) {
128   EXPECT_DCHECK_DEATH_WITH(GetProductInfoViaTask(), "ZX_ERR_PEER_CLOSED");
129 }
130 
131 }  // namespace base
132