summaryrefslogtreecommitdiffstats
path: root/chromium/base/fuchsia/scoped_service_binding_unittest.cc
blob: 4368055cad48c82613e70fd81d7c97fc9f9a0277 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2019 The Chromium 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 "base/fuchsia/scoped_service_binding.h"

#include "base/fuchsia/service_directory_test_base.h"
#include "base/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace fuchsia {

class ScopedServiceBindingTest : public ServiceDirectoryTestBase {};

// Verifies that ScopedServiceBinding allows connection more than once.
TEST_F(ScopedServiceBindingTest, ConnectTwice) {
  auto stub = public_service_directory_->Connect<testfidl::TestInterface>();
  auto stub2 = public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&stub, ZX_OK);
  VerifyTestInterface(&stub2, ZX_OK);
}

// Verify that if we connect twice to a prefer-new bound service, the existing
// connection gets closed.
TEST_F(ScopedServiceBindingTest, SingleClientPreferNew) {
  // Teardown the default multi-client binding and create a prefer-new one.
  service_binding_ = nullptr;
  ScopedSingleClientServiceBinding<testfidl::TestInterface,
                                   ScopedServiceBindingPolicy::kPreferNew>
      binding(outgoing_directory_.get(), &test_service_);

  // Connect the first client, and verify that it is functional.
  auto existing_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&existing_client, ZX_OK);

  // Connect the second client, so the existing one should be disconnected and
  // the new should be functional.
  auto new_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(existing_client);
  VerifyTestInterface(&new_client, ZX_OK);
}

// Verify that if we connect twice to a prefer-existing bound service, the new
// connection gets closed.
TEST_F(ScopedServiceBindingTest, SingleClientPreferExisting) {
  // Teardown the default multi-client binding and create a prefer-existing one.
  service_binding_ = nullptr;
  ScopedSingleClientServiceBinding<testfidl::TestInterface,
                                   ScopedServiceBindingPolicy::kPreferExisting>
      binding(outgoing_directory_.get(), &test_service_);

  // Connect the first client, and verify that it is functional.
  auto existing_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&existing_client, ZX_OK);

  // Connect the second client, then verify that the it gets closed and the
  // existing one remains functional.
  auto new_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(new_client);
  VerifyTestInterface(&existing_client, ZX_OK);
}

// Verify that the default single-client binding policy is prefer-new.
TEST_F(ScopedServiceBindingTest, SingleClientDefaultIsPreferNew) {
  // Teardown the default multi-client binding and create a prefer-new one.
  service_binding_ = nullptr;
  ScopedSingleClientServiceBinding<testfidl::TestInterface> binding(
      outgoing_directory_.get(), &test_service_);

  // Connect the first client, and verify that it is functional.
  auto existing_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&existing_client, ZX_OK);

  // Connect the second client, so the existing one should be disconnected and
  // the new should be functional.
  auto new_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(existing_client);
  VerifyTestInterface(&new_client, ZX_OK);
}

// Verify that we can publish a debug service.
TEST_F(ScopedServiceBindingTest, ConnectDebugService) {
  // Remove the public service binding.
  service_binding_.reset();

  // Publish the test service to the "debug" directory.
  ScopedServiceBinding<testfidl::TestInterface> debug_service_binding(
      outgoing_directory_->debug_dir(), &test_service_);

  auto debug_stub =
      debug_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&debug_stub, ZX_OK);

  auto release_stub =
      public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&release_stub, ZX_ERR_PEER_CLOSED);
}

TEST_F(ScopedServiceBindingTest, SingleBindingSetOnLastClientCallback) {
  service_binding_.reset();
  ScopedSingleClientServiceBinding<testfidl::TestInterface>
      single_service_binding(outgoing_directory_.get(), &test_service_);

  base::RunLoop run_loop;
  single_service_binding.SetOnLastClientCallback(run_loop.QuitClosure());

  auto current_client =
      public_service_directory_->Connect<testfidl::TestInterface>();
  VerifyTestInterface(&current_client, ZX_OK);
  current_client.Unbind();

  run_loop.Run();
}

}  // namespace fuchsia
}  // namespace base