1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "google/cloud/internal/future_impl.h"
16 #include "google/cloud/testing_util/chrono_literals.h"
17 #include "google/cloud/testing_util/expect_future_error.h"
18 #include "google/cloud/testing_util/testing_types.h"
19 #include "absl/memory/memory.h"
20 #include <gmock/gmock.h>
21 
22 namespace google {
23 namespace cloud {
24 inline namespace GOOGLE_CLOUD_CPP_NS {
25 namespace internal {
26 namespace {
27 
28 using ::testing::HasSubstr;
29 using testing_util::chrono_literals::operator"" _us;
30 using testing_util::ExpectFutureError;
31 using testing_util::NoDefaultConstructor;
32 using testing_util::Observable;
33 
TEST(FutureImplBaseTest,Basic)34 TEST(FutureImplBaseTest, Basic) {
35   future_shared_state_base shared_state;
36   EXPECT_FALSE(shared_state.is_ready());
37 }
38 
TEST(FutureImplBaseTest,WaitFor)39 TEST(FutureImplBaseTest, WaitFor) {
40   future_shared_state_base shared_state;
41   auto start = std::chrono::steady_clock::now();
42   auto s = shared_state.wait_for(100_us);
43   auto elapsed = std::chrono::steady_clock::now() - start;
44   EXPECT_EQ(static_cast<int>(s), static_cast<int>(std::future_status::timeout));
45   EXPECT_LE(100_us, elapsed);
46   EXPECT_FALSE(shared_state.is_ready());
47 }
48 
TEST(FutureImplBaseTest,WaitForReady)49 TEST(FutureImplBaseTest, WaitForReady) {
50   future_shared_state_base shared_state;
51   shared_state.set_exception(
52       std::make_exception_ptr(std::runtime_error("test_message")));
53   auto s = shared_state.wait_for(100_us);
54   EXPECT_EQ(std::future_status::ready, s);
55   EXPECT_TRUE(shared_state.is_ready());
56 }
57 
TEST(FutureImplBaseTest,WaitUntil)58 TEST(FutureImplBaseTest, WaitUntil) {
59   future_shared_state_base shared_state;
60   EXPECT_FALSE(shared_state.is_ready());
61   auto start = std::chrono::steady_clock::now();
62   auto s = shared_state.wait_until(std::chrono::system_clock::now() + 100_us);
63   auto elapsed = std::chrono::steady_clock::now() - start;
64   EXPECT_EQ(static_cast<int>(s), static_cast<int>(std::future_status::timeout));
65   EXPECT_LE(100_us, elapsed);
66   EXPECT_FALSE(shared_state.is_ready());
67 }
68 
TEST(FutureImplBaseTest,WaitUntilReady)69 TEST(FutureImplBaseTest, WaitUntilReady) {
70   future_shared_state_base shared_state;
71   shared_state.set_exception(
72       std::make_exception_ptr(std::runtime_error("test message")));
73   auto s = shared_state.wait_until(std::chrono::system_clock::now() + 100_us);
74   EXPECT_EQ(static_cast<int>(s), static_cast<int>(std::future_status::ready));
75   EXPECT_TRUE(shared_state.is_ready());
76 }
77 
TEST(FutureImplBaseTest,SetExceptionCanBeCalledOnlyOnce)78 TEST(FutureImplBaseTest, SetExceptionCanBeCalledOnlyOnce) {
79   future_shared_state_base shared_state;
80   EXPECT_FALSE(shared_state.is_ready());
81 
82   shared_state.set_exception(
83       std::make_exception_ptr(std::runtime_error("test message")));
84   EXPECT_TRUE(shared_state.is_ready());
85   ExpectFutureError(
86       [&] {
87         shared_state.set_exception(
88             std::make_exception_ptr(std::runtime_error("blah")));
89       },
90       std::future_errc::promise_already_satisfied);
91 
92   EXPECT_TRUE(shared_state.is_ready());
93 }
94 
TEST(FutureImplBaseTest,Abandon)95 TEST(FutureImplBaseTest, Abandon) {
96   future_shared_state_base shared_state;
97   shared_state.abandon();
98   EXPECT_TRUE(shared_state.is_ready());
99 }
100 
TEST(FutureImplBaseTest,AbandonReady)101 TEST(FutureImplBaseTest, AbandonReady) {
102   future_shared_state_base shared_state;
103   shared_state.set_exception(
104       std::make_exception_ptr(std::runtime_error("test message")));
105   shared_state.abandon();
106   SUCCEED();
107   EXPECT_TRUE(shared_state.is_ready());
108 }
109 
110 // @test Verify that we can create continuations.
TEST(ContinuationVoidTest,Constructor)111 TEST(ContinuationVoidTest, Constructor) {
112   auto functor = [](std::shared_ptr<future_shared_state<void>> const&) {};
113 
114   using tested_type = continuation<decltype(functor), void>;
115 
116   auto input = std::make_shared<future_shared_state<void>>();
117   auto cont = std::make_shared<tested_type>(std::move(functor), input);
118 
119   auto current = cont->input.lock();
120   EXPECT_EQ(input.get(), current.get());
121 }
122 
123 /// @test Verify that satisfying the shared state with an exception calls the
124 /// continuation.
TEST(ContinuationVoidTest,SetExceptionCallsContinuation)125 TEST(ContinuationVoidTest, SetExceptionCallsContinuation) {
126   bool called = false;
127   auto functor =
128       [&called](std::shared_ptr<future_shared_state<void>> const& state) {
129         called = true;
130         state->get();
131       };
132 
133   auto input = std::make_shared<future_shared_state<void>>();
134   std::shared_ptr<future_shared_state<void>> output =
135       input->make_continuation(input, std::move(functor));
136 
137 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
138   input->set_exception(
139       std::make_exception_ptr(std::runtime_error("test message")));
140   EXPECT_TRUE(called);
141   EXPECT_TRUE(output->is_ready());
142   EXPECT_THROW(
143       try { output->get(); } catch (std::runtime_error const& ex) {
144         EXPECT_THAT(ex.what(), HasSubstr("test message"));
145         throw;
146       },
147       std::runtime_error);
148 #else
149   EXPECT_DEATH_IF_SUPPORTED(
150       input->set_exception(
151           std::make_exception_ptr(std::runtime_error("test message"))),
152       "future<void>::get\\(\\) had an exception but exceptions are disabled");
153 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
154 }
155 
156 /// @test Verify that satisfying the shared state with a value calls the
157 /// continuation.
TEST(ContinuationVoidTest,SetValueCallsContinuation)158 TEST(ContinuationVoidTest, SetValueCallsContinuation) {
159   bool called = false;
160   auto functor =
161       [&called](std::shared_ptr<future_shared_state<void>> const& state) {
162         called = true;
163         state->get();
164       };
165 
166   auto input = std::make_shared<future_shared_state<void>>();
167   std::shared_ptr<future_shared_state<void>> output =
168       input->make_continuation(input, std::move(functor));
169 
170   input->set_value();
171   EXPECT_TRUE(called);
172   EXPECT_TRUE(output->is_ready());
173   output->get();
174   SUCCEED();
175 }
176 
177 class TestContinuation : public continuation_base {
178  public:
TestContinuation(int * r)179   explicit TestContinuation(int* r) : execute_counter(r) {}
execute()180   void execute() override { (*execute_counter)++; }
181 
182   int* execute_counter;
183 };
184 
TEST(FutureImplVoid,SetValue)185 TEST(FutureImplVoid, SetValue) {
186   future_shared_state<void> shared_state;
187   EXPECT_FALSE(shared_state.is_ready());
188   shared_state.set_value();
189   EXPECT_TRUE(shared_state.is_ready());
190   shared_state.get();
191   SUCCEED();
192 }
193 
TEST(FutureImplVoid,SetValueCanBeCalledOnlyOnce)194 TEST(FutureImplVoid, SetValueCanBeCalledOnlyOnce) {
195   future_shared_state<void> shared_state;
196   EXPECT_FALSE(shared_state.is_ready());
197 
198   shared_state.set_value();
199   ExpectFutureError([&] { shared_state.set_value(); },
200                     std::future_errc::promise_already_satisfied);
201 
202   shared_state.get();
203   SUCCEED();
204 }
205 
TEST(FutureImplVoid,GetException)206 TEST(FutureImplVoid, GetException) {
207   future_shared_state<void> shared_state;
208   EXPECT_FALSE(shared_state.is_ready());
209   shared_state.set_exception(
210       std::make_exception_ptr(std::runtime_error("test message")));
211   EXPECT_TRUE(shared_state.is_ready());
212 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
213   EXPECT_THROW(
214       try { shared_state.get(); } catch (std::runtime_error const& ex) {
215         EXPECT_THAT(ex.what(), HasSubstr("test message"));
216         throw;
217       },
218       std::runtime_error);
219 #else
220   EXPECT_DEATH_IF_SUPPORTED(
221       shared_state.get(),
222       "future<void>::get\\(\\) had an exception but exceptions are disabled");
223 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
224 }
225 
TEST(FutureImplVoid,Abandon)226 TEST(FutureImplVoid, Abandon) {
227   future_shared_state<void> shared_state;
228   shared_state.abandon();
229   EXPECT_TRUE(shared_state.is_ready());
230 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
231   EXPECT_THROW(
232       try { shared_state.get(); } catch (std::future_error const& ex) {
233         EXPECT_EQ(std::future_errc::broken_promise, ex.code());
234         throw;
235       },
236       std::future_error);
237 #else
238   EXPECT_DEATH_IF_SUPPORTED(
239       shared_state.get(),
240       "future<void>::get\\(\\) had an exception but exceptions are disabled");
241 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
242 }
243 
TEST(FutureImplVoid,SetContinuation)244 TEST(FutureImplVoid, SetContinuation) {
245   future_shared_state<void> shared_state;
246   EXPECT_FALSE(shared_state.is_ready());
247 
248   int execute_counter = 0;
249   shared_state.set_continuation(
250       absl::make_unique<TestContinuation>(&execute_counter));
251   EXPECT_EQ(0, execute_counter);
252   EXPECT_FALSE(shared_state.is_ready());
253   shared_state.set_value();
254   EXPECT_EQ(1, execute_counter);
255 
256   shared_state.get();
257   SUCCEED();
258 }
259 
TEST(FutureImplVoid,SetContinuationAlreadySet)260 TEST(FutureImplVoid, SetContinuationAlreadySet) {
261   future_shared_state<void> shared_state;
262   EXPECT_FALSE(shared_state.is_ready());
263 
264   int execute_counter = 0;
265   shared_state.set_continuation(
266       absl::make_unique<TestContinuation>(&execute_counter));
267 
268   ExpectFutureError(
269       [&] {
270         shared_state.set_continuation(
271             absl::make_unique<TestContinuation>(&execute_counter));
272       },
273       std::future_errc::future_already_retrieved);
274 }
275 
TEST(FutureImplVoid,SetContinuationAlreadySatisfied)276 TEST(FutureImplVoid, SetContinuationAlreadySatisfied) {
277   future_shared_state<void> shared_state;
278   EXPECT_FALSE(shared_state.is_ready());
279 
280   int execute_counter = 0;
281   shared_state.set_value();
282   EXPECT_EQ(0, execute_counter);
283   shared_state.set_continuation(
284       absl::make_unique<TestContinuation>(&execute_counter));
285   EXPECT_EQ(1, execute_counter);
286 
287   shared_state.get();
288   SUCCEED();
289 }
290 
TEST(FutureImplVoid,MarkRetrieved)291 TEST(FutureImplVoid, MarkRetrieved) {
292   auto sh = std::make_shared<future_shared_state<void>>();
293   future_shared_state<void>::mark_retrieved(sh);
294   SUCCEED();
295 }
296 
TEST(FutureImplVoid,MarkRetrievedCanBeCalledOnlyOnce)297 TEST(FutureImplVoid, MarkRetrievedCanBeCalledOnlyOnce) {
298   auto sh = std::make_shared<future_shared_state<void>>();
299   future_shared_state<void>::mark_retrieved(sh);
300   ExpectFutureError([&] { future_shared_state<void>::mark_retrieved(sh); },
301                     std::future_errc::future_already_retrieved);
302 }
303 
TEST(FutureImplVoid,MarkRetrievedFailure)304 TEST(FutureImplVoid, MarkRetrievedFailure) {
305   std::shared_ptr<future_shared_state<void>> sh;
306   ExpectFutureError([&] { future_shared_state<void>::mark_retrieved(sh); },
307                     std::future_errc::no_state);
308 }
309 
TEST(FutureImplInt,SetException)310 TEST(FutureImplInt, SetException) {
311   future_shared_state<int> shared_state;
312   EXPECT_FALSE(shared_state.is_ready());
313 
314   shared_state.set_exception(
315       std::make_exception_ptr(std::runtime_error("test message")));
316   EXPECT_TRUE(shared_state.is_ready());
317 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
318   EXPECT_THROW(
319       try { shared_state.get(); } catch (std::runtime_error const& ex) {
320         EXPECT_THAT(ex.what(), HasSubstr("test message"));
321         throw;
322       },
323       std::runtime_error);
324 #else
325   std::cerr << "About to die\n";
326   EXPECT_DEATH_IF_SUPPORTED(
327       shared_state.get(),
328       "future<T>::get\\(\\) had an exception but exceptions are disabled");
329 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
330 }
331 
TEST(FutureImplInt,SetValue)332 TEST(FutureImplInt, SetValue) {
333   future_shared_state<int> shared_state;
334   EXPECT_FALSE(shared_state.is_ready());
335   shared_state.set_value(42);
336   EXPECT_TRUE(shared_state.is_ready());
337   EXPECT_EQ(42, shared_state.get());
338 }
339 
TEST(FutureImplInt,SetValueCanBeCalledOnlyOnce)340 TEST(FutureImplInt, SetValueCanBeCalledOnlyOnce) {
341   future_shared_state<int> shared_state;
342   EXPECT_FALSE(shared_state.is_ready());
343 
344   shared_state.set_value(42);
345   ExpectFutureError([&] { shared_state.set_value(42); },
346                     std::future_errc::promise_already_satisfied);
347 
348   EXPECT_EQ(42, shared_state.get());
349 }
350 
TEST(FutureImplInt,GetException)351 TEST(FutureImplInt, GetException) {
352   future_shared_state<int> shared_state;
353   EXPECT_FALSE(shared_state.is_ready());
354   shared_state.set_exception(
355       std::make_exception_ptr(std::runtime_error("test message")));
356   EXPECT_TRUE(shared_state.is_ready());
357 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
358   EXPECT_THROW(
359       try { shared_state.get(); } catch (std::runtime_error const& ex) {
360         EXPECT_THAT(ex.what(), HasSubstr("test message"));
361         throw;
362       },
363       std::runtime_error);
364 #else
365   EXPECT_DEATH_IF_SUPPORTED(
366       shared_state.get(),
367       "future<T>::get\\(\\) had an exception but exceptions are disabled");
368 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
369 }
370 
TEST(FutureImplInt,Abandon)371 TEST(FutureImplInt, Abandon) {
372   future_shared_state<int> shared_state;
373   shared_state.abandon();
374   EXPECT_TRUE(shared_state.is_ready());
375 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
376   EXPECT_THROW(
377       try { shared_state.get(); } catch (std::future_error const& ex) {
378         EXPECT_EQ(std::future_errc::broken_promise, ex.code());
379         throw;
380       },
381       std::future_error);
382 #else
383   EXPECT_DEATH_IF_SUPPORTED(
384       shared_state.get(),
385       "future<T>::get\\(\\) had an exception but exceptions are disabled");
386 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
387 }
388 
TEST(FutureImplInt,MarkRetrieved)389 TEST(FutureImplInt, MarkRetrieved) {
390   auto sh = std::make_shared<future_shared_state<int>>();
391   future_shared_state<int>::mark_retrieved(sh);
392   SUCCEED();
393 }
394 
TEST(FutureImplInt,MarkRetrievedCanBeCalledOnlyOnce)395 TEST(FutureImplInt, MarkRetrievedCanBeCalledOnlyOnce) {
396   auto sh = std::make_shared<future_shared_state<int>>();
397   future_shared_state<int>::mark_retrieved(sh);
398   ExpectFutureError([&] { future_shared_state<int>::mark_retrieved(sh); },
399                     std::future_errc::future_already_retrieved);
400 }
401 
TEST(FutureImplInt,MarkRetrievedFailure)402 TEST(FutureImplInt, MarkRetrievedFailure) {
403   std::shared_ptr<future_shared_state<int>> sh;
404   ExpectFutureError([&] { future_shared_state<int>::mark_retrieved(sh); },
405                     std::future_errc::no_state);
406 }
407 
TEST(FutureImplInt,SetContinuation)408 TEST(FutureImplInt, SetContinuation) {
409   future_shared_state<int> shared_state;
410   EXPECT_FALSE(shared_state.is_ready());
411 
412   int execute_counter = 0;
413   shared_state.set_continuation(
414       absl::make_unique<TestContinuation>(&execute_counter));
415   EXPECT_EQ(0, execute_counter);
416   EXPECT_FALSE(shared_state.is_ready());
417   shared_state.set_value(42);
418   EXPECT_EQ(1, execute_counter);
419 
420   shared_state.get();
421   SUCCEED();
422 }
423 
TEST(FutureImplInt,SetContinuationAlreadySet)424 TEST(FutureImplInt, SetContinuationAlreadySet) {
425   future_shared_state<int> shared_state;
426   EXPECT_FALSE(shared_state.is_ready());
427 
428   int execute_counter = 0;
429   shared_state.set_continuation(
430       absl::make_unique<TestContinuation>(&execute_counter));
431   ExpectFutureError(
432       [&] {
433         shared_state.set_continuation(
434             absl::make_unique<TestContinuation>(&execute_counter));
435       },
436       std::future_errc::future_already_retrieved);
437 }
438 
TEST(FutureImplInt,SetContinuationAlreadySatisfied)439 TEST(FutureImplInt, SetContinuationAlreadySatisfied) {
440   future_shared_state<int> shared_state;
441   EXPECT_FALSE(shared_state.is_ready());
442 
443   int execute_counter = 0;
444   shared_state.set_value(42);
445   EXPECT_EQ(0, execute_counter);
446   shared_state.set_continuation(
447       absl::make_unique<TestContinuation>(&execute_counter));
448   EXPECT_EQ(1, execute_counter);
449 
450   EXPECT_EQ(42, shared_state.get());
451 }
452 
453 // @test Verify that we can create continuations.
TEST(ContinuationIntTest,Constructor)454 TEST(ContinuationIntTest, Constructor) {
455   auto functor = [](std::shared_ptr<future_shared_state<int>> const&) {};
456 
457   using tested_type = continuation<decltype(functor), int>;
458 
459   auto input = std::make_shared<future_shared_state<int>>();
460   auto cont = std::make_shared<tested_type>(std::move(functor), input);
461 
462   auto current = cont->input.lock();
463   EXPECT_EQ(input.get(), current.get());
464 }
465 
466 /// @test Verify that satisfying the shared state with an exception calls the
467 /// continuation.
TEST(ContinuationIntTest,SetExceptionCallsContinuation)468 TEST(ContinuationIntTest, SetExceptionCallsContinuation) {
469   bool called = false;
470   auto functor =
471       [&called](std::shared_ptr<future_shared_state<int>> const& state) {
472         called = true;
473         return 2 * state->get();
474       };
475 
476   auto input = std::make_shared<future_shared_state<int>>();
477   std::shared_ptr<future_shared_state<int>> output =
478       input->make_continuation(input, std::move(functor));
479 
480 #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
481   input->set_exception(
482       std::make_exception_ptr(std::runtime_error("test message")));
483   EXPECT_TRUE(called);
484   EXPECT_TRUE(output->is_ready());
485   EXPECT_THROW(
486       try { output->get(); } catch (std::runtime_error const& ex) {
487         EXPECT_THAT(ex.what(), HasSubstr("test message"));
488         throw;
489       },
490       std::runtime_error);
491 #else
492   EXPECT_DEATH_IF_SUPPORTED(
493       input->set_exception(
494           std::make_exception_ptr(std::runtime_error("test message"))),
495       "future<T>::get\\(\\) had an exception but exceptions are disabled");
496 #endif  // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
497 }
498 
499 /// @test Verify that satisfying the shared state with a value calls the
500 /// continuation.
TEST(ContinuationIntTest,SetValueCallsContinuation)501 TEST(ContinuationIntTest, SetValueCallsContinuation) {
502   bool called = false;
503   auto functor =
504       [&called](std::shared_ptr<future_shared_state<int>> const& state) {
505         called = true;
506         return 2 * state->get();
507       };
508 
509   auto input = std::make_shared<future_shared_state<int>>();
510   std::shared_ptr<future_shared_state<int>> output =
511       input->make_continuation(input, std::move(functor));
512 
513   input->set_value(42);
514   EXPECT_TRUE(called);
515   EXPECT_TRUE(output->is_ready());
516   EXPECT_EQ(84, output->get());
517 }
518 
TEST(FutureImplNoDefaultConstructor,SetValue)519 TEST(FutureImplNoDefaultConstructor, SetValue) {
520   future_shared_state<NoDefaultConstructor> shared_state;
521   EXPECT_FALSE(shared_state.is_ready());
522 
523   shared_state.set_value(NoDefaultConstructor("42"));
524   EXPECT_TRUE(shared_state.is_ready());
525 
526   NoDefaultConstructor result = shared_state.get();
527   EXPECT_EQ("42", result.str());
528 }
529 
TEST(FutureImplObservable,NeverSet)530 TEST(FutureImplObservable, NeverSet) {
531   Observable::reset_counters();
532   {
533     future_shared_state<Observable> shared_state;
534     EXPECT_FALSE(shared_state.is_ready());
535     EXPECT_EQ(0, Observable::default_constructor());
536     EXPECT_EQ(0, Observable::destructor());
537   }
538   EXPECT_EQ(0, Observable::default_constructor());
539   EXPECT_EQ(0, Observable::destructor());
540 }
541 
TEST(FutureImplObservable,SetValue)542 TEST(FutureImplObservable, SetValue) {
543   Observable::reset_counters();
544   {
545     future_shared_state<Observable> shared_state;
546     EXPECT_FALSE(shared_state.is_ready());
547 
548     shared_state.set_value(Observable("set value"));
549     EXPECT_EQ(0, Observable::default_constructor());
550     EXPECT_EQ(1, Observable::value_constructor());
551     EXPECT_EQ(0, Observable::copy_constructor());
552     EXPECT_EQ(1, Observable::move_constructor());
553     EXPECT_EQ(0, Observable::copy_assignment());
554     EXPECT_EQ(0, Observable::move_assignment());
555     EXPECT_EQ(1, Observable::destructor());
556     {
557       Observable value = shared_state.get();
558       EXPECT_EQ(0, Observable::default_constructor());
559       EXPECT_EQ(1, Observable::value_constructor());
560       EXPECT_EQ(0, Observable::copy_constructor());
561       EXPECT_EQ(2, Observable::move_constructor());
562       EXPECT_EQ(0, Observable::copy_assignment());
563       EXPECT_EQ(0, Observable::move_assignment());
564       EXPECT_EQ(1, Observable::destructor());
565     }
566     EXPECT_EQ(0, Observable::default_constructor());
567     EXPECT_EQ(1, Observable::value_constructor());
568     EXPECT_EQ(0, Observable::copy_constructor());
569     EXPECT_EQ(2, Observable::move_constructor());
570     EXPECT_EQ(0, Observable::copy_assignment());
571     EXPECT_EQ(0, Observable::move_assignment());
572     EXPECT_EQ(2, Observable::destructor());
573   }
574   EXPECT_EQ(0, Observable::default_constructor());
575   EXPECT_EQ(1, Observable::value_constructor());
576   EXPECT_EQ(0, Observable::copy_constructor());
577   EXPECT_EQ(2, Observable::move_constructor());
578   EXPECT_EQ(0, Observable::copy_assignment());
579   EXPECT_EQ(0, Observable::move_assignment());
580   EXPECT_EQ(3, Observable::destructor());
581 }
582 
583 }  // namespace
584 }  // namespace internal
585 }  // namespace GOOGLE_CLOUD_CPP_NS
586 }  // namespace cloud
587 }  // namespace google
588