123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- // Copyright 2018 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 "services/audio/test/mock_group_coordinator.h"
- #include "base/containers/contains.h"
- #include "base/unguessable_token.h"
- #include "services/audio/test/mock_group_member.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using base::UnguessableToken;
- using testing::AtLeast;
- using testing::NiceMock;
- using testing::ReturnRef;
- using testing::Sequence;
- using testing::StrictMock;
- using testing::_;
- namespace audio {
- class TestGroupCoordinator : public GroupCoordinator<MockGroupMember> {
- public:
- const std::vector<MockGroupMember*>& GetCurrentMembers(
- const base::UnguessableToken& group_id) const {
- return GetCurrentMembersUnsafe(group_id);
- }
- };
- namespace {
- class MockGroupObserver : public TestGroupCoordinator::Observer {
- public:
- MockGroupObserver() = default;
- MockGroupObserver(const MockGroupObserver&) = delete;
- MockGroupObserver& operator=(const MockGroupObserver&) = delete;
- ~MockGroupObserver() override = default;
- MOCK_METHOD1(OnMemberJoinedGroup, void(MockGroupMember* member));
- MOCK_METHOD1(OnMemberLeftGroup, void(MockGroupMember* member));
- };
- TEST(GroupCoordinatorTest, NeverUsed) {
- TestGroupCoordinator coordinator;
- }
- TEST(GroupCoordinatorTest, RegistersMembersInSameGroup) {
- const UnguessableToken group_id = UnguessableToken::Create();
- StrictMock<MockGroupMember> member1;
- StrictMock<MockGroupMember> member2;
- // An observer should see each member join and leave the group once.
- StrictMock<MockGroupObserver> observer;
- Sequence join_leave_sequence;
- EXPECT_CALL(observer, OnMemberJoinedGroup(&member1))
- .InSequence(join_leave_sequence);
- EXPECT_CALL(observer, OnMemberJoinedGroup(&member2))
- .InSequence(join_leave_sequence);
- EXPECT_CALL(observer, OnMemberLeftGroup(&member1))
- .InSequence(join_leave_sequence);
- EXPECT_CALL(observer, OnMemberLeftGroup(&member2))
- .InSequence(join_leave_sequence);
- TestGroupCoordinator coordinator;
- coordinator.AddObserver(group_id, &observer);
- coordinator.RegisterMember(group_id, &member1);
- coordinator.RegisterMember(group_id, &member2);
- const std::vector<MockGroupMember*>& members =
- coordinator.GetCurrentMembers(group_id);
- EXPECT_EQ(2u, members.size());
- EXPECT_TRUE(base::Contains(members, &member1));
- EXPECT_TRUE(base::Contains(members, &member2));
- EXPECT_TRUE(
- coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());
- coordinator.UnregisterMember(group_id, &member1);
- coordinator.UnregisterMember(group_id, &member2);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
- coordinator.RemoveObserver(group_id, &observer);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
- }
- TEST(GroupCoordinatorTest, RegistersMembersInDifferentGroups) {
- const UnguessableToken group_id_a = UnguessableToken::Create();
- StrictMock<MockGroupMember> member_a_1;
- StrictMock<MockGroupMember> member_a_2;
- StrictMock<MockGroupObserver> observer_a;
- Sequence join_leave_sequence_a;
- EXPECT_CALL(observer_a, OnMemberJoinedGroup(&member_a_1))
- .InSequence(join_leave_sequence_a);
- EXPECT_CALL(observer_a, OnMemberJoinedGroup(&member_a_2))
- .InSequence(join_leave_sequence_a);
- EXPECT_CALL(observer_a, OnMemberLeftGroup(&member_a_1))
- .InSequence(join_leave_sequence_a);
- EXPECT_CALL(observer_a, OnMemberLeftGroup(&member_a_2))
- .InSequence(join_leave_sequence_a);
- const UnguessableToken group_id_b = UnguessableToken::Create();
- StrictMock<MockGroupMember> member_b_1;
- StrictMock<MockGroupObserver> observer_b;
- Sequence join_leave_sequence_b;
- EXPECT_CALL(observer_b, OnMemberJoinedGroup(&member_b_1))
- .InSequence(join_leave_sequence_b);
- EXPECT_CALL(observer_b, OnMemberLeftGroup(&member_b_1))
- .InSequence(join_leave_sequence_b);
- TestGroupCoordinator coordinator;
- coordinator.AddObserver(group_id_a, &observer_a);
- coordinator.AddObserver(group_id_b, &observer_b);
- coordinator.RegisterMember(group_id_a, &member_a_1);
- coordinator.RegisterMember(group_id_b, &member_b_1);
- coordinator.RegisterMember(group_id_a, &member_a_2);
- const std::vector<MockGroupMember*>& members_a =
- coordinator.GetCurrentMembers(group_id_a);
- EXPECT_EQ(2u, members_a.size());
- EXPECT_TRUE(base::Contains(members_a, &member_a_1));
- EXPECT_TRUE(base::Contains(members_a, &member_a_2));
- EXPECT_EQ(std::vector<MockGroupMember*>({&member_b_1}),
- coordinator.GetCurrentMembers(group_id_b));
- EXPECT_TRUE(
- coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());
- coordinator.UnregisterMember(group_id_a, &member_a_1);
- EXPECT_EQ(std::vector<MockGroupMember*>({&member_a_2}),
- coordinator.GetCurrentMembers(group_id_a));
- coordinator.UnregisterMember(group_id_b, &member_b_1);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_b).empty());
- coordinator.UnregisterMember(group_id_a, &member_a_2);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_a).empty());
- coordinator.RemoveObserver(group_id_a, &observer_a);
- coordinator.RemoveObserver(group_id_b, &observer_b);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_a).empty());
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_b).empty());
- }
- TEST(GroupCoordinatorTest, TracksMembersWithoutAnObserverPresent) {
- const UnguessableToken group_id = UnguessableToken::Create();
- StrictMock<MockGroupMember> member1;
- StrictMock<MockGroupMember> member2;
- TestGroupCoordinator coordinator;
- coordinator.RegisterMember(group_id, &member1);
- coordinator.RegisterMember(group_id, &member2);
- const std::vector<MockGroupMember*>& members =
- coordinator.GetCurrentMembers(group_id);
- EXPECT_EQ(2u, members.size());
- EXPECT_TRUE(base::Contains(members, &member1));
- EXPECT_TRUE(base::Contains(members, &member2));
- EXPECT_TRUE(
- coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());
- coordinator.UnregisterMember(group_id, &member1);
- coordinator.UnregisterMember(group_id, &member2);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
- }
- TEST(GroupCoordinatorTest, NotifiesOnlyWhileObserving) {
- const UnguessableToken group_id = UnguessableToken::Create();
- StrictMock<MockGroupMember> member1;
- StrictMock<MockGroupMember> member2;
- // The observer will only be around at the time when member2 joins the group
- // and when member1 leaves the group.
- StrictMock<MockGroupObserver> observer;
- Sequence join_leave_sequence;
- EXPECT_CALL(observer, OnMemberJoinedGroup(&member1)).Times(0);
- EXPECT_CALL(observer, OnMemberJoinedGroup(&member2))
- .InSequence(join_leave_sequence);
- EXPECT_CALL(observer, OnMemberLeftGroup(&member1))
- .InSequence(join_leave_sequence);
- EXPECT_CALL(observer, OnMemberLeftGroup(&member2)).Times(0);
- TestGroupCoordinator coordinator;
- coordinator.RegisterMember(group_id, &member1);
- EXPECT_EQ(std::vector<MockGroupMember*>({&member1}),
- coordinator.GetCurrentMembers(group_id));
- coordinator.AddObserver(group_id, &observer);
- coordinator.RegisterMember(group_id, &member2);
- const std::vector<MockGroupMember*>& members =
- coordinator.GetCurrentMembers(group_id);
- EXPECT_EQ(2u, members.size());
- EXPECT_TRUE(base::Contains(members, &member1));
- EXPECT_TRUE(base::Contains(members, &member2));
- coordinator.UnregisterMember(group_id, &member1);
- EXPECT_EQ(std::vector<MockGroupMember*>({&member2}),
- coordinator.GetCurrentMembers(group_id));
- coordinator.RemoveObserver(group_id, &observer);
- EXPECT_EQ(std::vector<MockGroupMember*>({&member2}),
- coordinator.GetCurrentMembers(group_id));
- coordinator.UnregisterMember(group_id, &member2);
- EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
- }
- } // namespace
- } // namespace audio
|