Mir

Merge lp:~kdub/mir/fix-1626503 into lp:mir

Proposed by Kevin DuBois on 2016-09-22
Status: Merged
Approved by: Daniel van Vugt on 2016-09-27
Approved revision: 3720
Merged at revision: 3719
Proposed branch: lp:~kdub/mir/fix-1626503
Merge into: lp:mir
Diff against target: 383 lines (+111/-9)
12 files modified
src/client/buffer_vault.cpp (+9/-0)
src/client/mir_connection.cpp (+1/-1)
src/client/surface_map.cpp (+7/-7)
src/server/compositor/multi_monitor_arbiter.cpp (+11/-0)
src/server/compositor/multi_monitor_arbiter.h (+1/-0)
src/server/compositor/stream.cpp (+6/-0)
src/server/compositor/stream.h (+1/-0)
tests/acceptance-tests/throwback/test_presentation_chain.cpp (+51/-0)
tests/integration-tests/test_buffer_scheduling.cpp (+4/-0)
tests/unit-tests/client/test_mir_connection.cpp (+1/-1)
tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp (+13/-0)
tests/unit-tests/compositor/test_stream.cpp (+6/-0)
To merge this branch: bzr merge lp:~kdub/mir/fix-1626503
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve on 2016-09-27
Brandon Schaefer (community) 2016-09-22 Approve on 2016-09-23
Mir CI Bot continuous-integration Approve on 2016-09-22
Review via email: mp+306480@code.launchpad.net

Commit message

mir_presentation_chain api:
fix situation where where the server would not notify a client of a buffers return, following the destruction of the MirPresentationChain that the buffer was associated with.

fixes: LP: #1626503

Description of the change

mir_presentation_chain api:
fix situation where where the server would not notify a client of a buffers return, following the destruction of the MirPresentationChain that the buffer was associated with.

fixes: LP: #1626503

To post a comment you must log in.
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:3718
https://mir-jenkins.ubuntu.com/job/mir-ci/1784/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/2234/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2297
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2288
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2288
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2288
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2262/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2262
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2262/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2262
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2262/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2262
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2262/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2262/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/1784/rebuild

review: Needs Fixing (continuous-integration)
lp:~kdub/mir/fix-1626503 updated on 2016-09-22
3719. By Kevin DuBois on 2016-09-22

fix double paren complaint in clang

3720. By Kevin DuBois on 2016-09-22

fix issue with presentationchain suite

Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3720
https://mir-jenkins.ubuntu.com/job/mir-ci/1789/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/2239
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2302
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2293
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2293
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2293
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2267
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2267/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2267
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2267/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2267
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2267/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2267
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2267/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2267
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2267/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/1789/rebuild

review: Approve (continuous-integration)
Daniel van Vugt (vanvugt) wrote :

It's worth noting MultiMonitorArbiter will get deprecated and possibly removed soon enough (hopefully). As swap interval 1 throttling moves out of libmirserver and into libmirclient (using high-precision frame sync timing), it won't be needed any more.

Brandon Schaefer (brandontschaefer) wrote :

Im not super familiar with the context but the code looks good to me.

review: Approve
Kevin DuBois (kdub) wrote :

> It's worth noting MultiMonitorArbiter will get deprecated and possibly removed
> soon enough (hopefully). As swap interval 1 throttling moves out of
> libmirserver and into libmirclient (using high-precision frame sync timing),
> it won't be needed any more.

Hmm, news to me. I suppose some logic in there won't be needed, but some system of handing the buffers out will still be present, we might to need to sync on the plans.

Alexandros Frantzis (afrantzis) wrote :

Looks good.

Nit:
+ for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end(); it++)
+ {
+ if (it->use_count == 0)
+ map->send_buffer(it->buffer->id());
+ }

Why not use a range-based for loop?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/client/buffer_vault.cpp'
2--- src/client/buffer_vault.cpp 2016-07-05 12:40:56 +0000
3+++ src/client/buffer_vault.cpp 2016-09-22 19:03:27 +0000
4@@ -45,6 +45,9 @@
5
6 namespace
7 {
8+void ignore_buffer(MirBuffer*, void*)
9+{
10+}
11 void incoming_buffer(MirBuffer* buffer, void* context)
12 {
13 auto vault = static_cast<mcl::BufferVault*>(context);
14@@ -80,9 +83,15 @@
15 return;
16
17 buffer_factory->cancel_requests_with_context(this);
18+ std::unique_lock<std::mutex> lk(mutex);
19 for (auto& it : buffers)
20 try
21 {
22+ if (auto map = surface_map.lock())
23+ {
24+ auto buffer = map->buffer(it.first);
25+ buffer->set_callback(ignore_buffer, nullptr);
26+ }
27 free_buffer(it.first);
28 }
29 catch (...)
30
31=== modified file 'src/client/mir_connection.cpp'
32--- src/client/mir_connection.cpp 2016-08-31 10:47:16 +0000
33+++ src/client/mir_connection.cpp 2016-09-22 19:03:27 +0000
34@@ -1223,7 +1223,7 @@
35 void MirConnection::release_presentation_chain(MirPresentationChain* chain)
36 {
37 auto id = chain->rpc_id();
38- if (id > 0)
39+ if (id >= 0)
40 {
41 StreamRelease stream_release{nullptr, nullptr, nullptr, nullptr, chain->rpc_id()};
42 mp::BufferStreamId buffer_stream_id;
43
44=== modified file 'src/client/surface_map.cpp'
45--- src/client/surface_map.cpp 2016-06-06 11:51:31 +0000
46+++ src/client/surface_map.cpp 2016-09-22 19:03:27 +0000
47@@ -60,7 +60,7 @@
48 void mcl::ConnectionSurfaceMap::with_stream_do(
49 mf::BufferStreamId stream_id, std::function<void(ClientBufferStream*)> const& exec) const
50 {
51- std::shared_lock<decltype(guard)> lk(guard);
52+ std::shared_lock<decltype(stream_guard)> lk(stream_guard);
53 auto const it = streams.find(stream_id);
54 if (it != streams.end())
55 {
56@@ -78,7 +78,7 @@
57
58 void mcl::ConnectionSurfaceMap::with_all_streams_do(std::function<void(ClientBufferStream*)> const& fn) const
59 {
60- std::shared_lock<decltype(guard)> lk(guard);
61+ std::shared_lock<decltype(stream_guard)> lk(stream_guard);
62 for(auto const& stream : streams)
63 fn(stream.second.get());
64 }
65@@ -86,7 +86,7 @@
66 void mcl::ConnectionSurfaceMap::insert(
67 mf::BufferStreamId stream_id, std::shared_ptr<ClientBufferStream> const& stream)
68 {
69- std::lock_guard<decltype(guard)> lk(guard);
70+ std::lock_guard<decltype(stream_guard)> lk(stream_guard);
71 streams[stream_id] = stream;
72 }
73
74@@ -99,7 +99,7 @@
75
76 void mcl::ConnectionSurfaceMap::erase(mf::BufferStreamId stream_id)
77 {
78- std::lock_guard<decltype(guard)> lk(guard);
79+ std::lock_guard<decltype(stream_guard)> lk(stream_guard);
80 auto stream_it = streams.find(stream_id);
81 auto chain_it = chains.find(stream_id);
82 if (stream_it != streams.end())
83@@ -110,19 +110,19 @@
84
85 void mcl::ConnectionSurfaceMap::insert(int buffer_id, std::shared_ptr<mcl::MirBuffer> const& buffer)
86 {
87- std::lock_guard<decltype(guard)> lk(guard);
88+ std::lock_guard<decltype(buffer_guard)> lk(buffer_guard);
89 buffers[buffer_id] = buffer;
90 }
91
92 void mcl::ConnectionSurfaceMap::erase(int buffer_id)
93 {
94- std::lock_guard<decltype(guard)> lk(guard);
95+ std::lock_guard<decltype(buffer_guard)> lk(buffer_guard);
96 buffers.erase(buffer_id);
97 }
98
99 std::shared_ptr<mcl::MirBuffer> mcl::ConnectionSurfaceMap::buffer(int buffer_id) const
100 {
101- std::shared_lock<decltype(guard)> lk(guard);
102+ std::shared_lock<decltype(buffer_guard)> lk(buffer_guard);
103 auto const it = buffers.find(buffer_id);
104 if (it != buffers.end())
105 return it->second;
106
107=== modified file 'src/server/compositor/multi_monitor_arbiter.cpp'
108--- src/server/compositor/multi_monitor_arbiter.cpp 2016-05-03 06:55:25 +0000
109+++ src/server/compositor/multi_monitor_arbiter.cpp 2016-09-22 19:03:27 +0000
110@@ -39,6 +39,17 @@
111 {
112 }
113
114+mc::MultiMonitorArbiter::~MultiMonitorArbiter()
115+{
116+ std::lock_guard<decltype(mutex)> lk(mutex);
117+ for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end(); it++)
118+ {
119+ if (it->use_count == 0)
120+ map->send_buffer(it->buffer->id());
121+ }
122+
123+}
124+
125 std::shared_ptr<mg::Buffer> mc::MultiMonitorArbiter::compositor_acquire(compositor::CompositorID id)
126 {
127 std::lock_guard<decltype(mutex)> lk(mutex);
128
129=== modified file 'src/server/compositor/multi_monitor_arbiter.h'
130--- src/server/compositor/multi_monitor_arbiter.h 2016-05-03 06:55:25 +0000
131+++ src/server/compositor/multi_monitor_arbiter.h 2016-09-22 19:03:27 +0000
132@@ -41,6 +41,7 @@
133 MultiMonitorMode mode,
134 std::shared_ptr<frontend::ClientBuffers> const& map,
135 std::shared_ptr<Schedule> const& schedule);
136+ ~MultiMonitorArbiter();
137
138 std::shared_ptr<graphics::Buffer> compositor_acquire(compositor::CompositorID id) override;
139 void compositor_release(std::shared_ptr<graphics::Buffer> const&) override;
140
141=== modified file 'src/server/compositor/stream.cpp'
142--- src/server/compositor/stream.cpp 2016-06-02 05:33:50 +0000
143+++ src/server/compositor/stream.cpp 2016-09-22 19:03:27 +0000
144@@ -73,6 +73,12 @@
145 {
146 }
147
148+mc::Stream::~Stream()
149+{
150+ while(schedule->num_scheduled())
151+ buffers->send_buffer(schedule->next_buffer()->id());
152+}
153+
154 unsigned int mc::Stream::client_owned_buffer_count(std::lock_guard<decltype(mutex)> const&) const
155 {
156 auto server_count = schedule->num_scheduled();
157
158=== modified file 'src/server/compositor/stream.h'
159--- src/server/compositor/stream.h 2016-05-04 01:48:16 +0000
160+++ src/server/compositor/stream.h 2016-09-22 19:03:27 +0000
161@@ -44,6 +44,7 @@
162 Stream(
163 FrameDroppingPolicyFactory const& policy_factory,
164 std::shared_ptr<frontend::ClientBuffers>, geometry::Size sz, MirPixelFormat format);
165+ ~Stream();
166
167 void swap_buffers(
168 graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
169
170=== modified file 'tests/acceptance-tests/throwback/test_presentation_chain.cpp'
171--- tests/acceptance-tests/throwback/test_presentation_chain.cpp 2016-08-23 16:18:08 +0000
172+++ tests/acceptance-tests/throwback/test_presentation_chain.cpp 2016-09-22 19:03:27 +0000
173@@ -188,6 +188,10 @@
174 unsigned int callback_count = 0;
175 };
176
177+void ignore_callback(MirBuffer*, void*)
178+{
179+}
180+
181 void buffer_callback(MirBuffer* buffer, void* context)
182 {
183 auto sync = reinterpret_cast<MirBufferSync*>(context);
184@@ -292,6 +296,9 @@
185 if (i != 0)
186 ASSERT_TRUE(contexts[(i-1) % num_buffers].wait_for_buffer(10s)) << "iteration " << i;
187 }
188+
189+ for (auto& context : contexts)
190+ mir_buffer_set_callback(context.buffer(), ignore_callback, nullptr);
191 }
192
193 TEST_F(PresentationChain, submission_will_eventually_call_callback_reassociated)
194@@ -318,6 +325,8 @@
195 if (i != 0)
196 ASSERT_TRUE(contexts[(i-1) % num_buffers].wait_for_buffer(10s)) << "iteration " << i;
197 }
198+ for (auto& context : contexts)
199+ mir_buffer_set_callback(context.buffer(), ignore_callback, nullptr);
200 }
201
202 TEST_F(PresentationChain, buffers_can_be_destroyed_before_theyre_returned)
203@@ -336,6 +345,45 @@
204 mir_buffer_release(context.buffer());
205 }
206
207+TEST_F(PresentationChain, destroying_a_chain_will_return_buffers_associated_with_chain)
208+{
209+ auto chain = mir_connection_create_presentation_chain_sync(connection);
210+ auto stream = mir_connection_create_buffer_stream_sync(connection, 25, 12, mir_pixel_format_abgr_8888, mir_buffer_usage_hardware);
211+ ASSERT_TRUE(mir_presentation_chain_is_valid(chain));
212+
213+ auto spec = mir_connection_create_spec_for_normal_surface(
214+ connection, size.width.as_int(), size.height.as_int(), pf);
215+ auto surface = mir_surface_create_sync(spec);
216+ mir_surface_spec_release(spec);
217+
218+ spec = mir_connection_create_spec_for_changes(connection);
219+ mir_surface_spec_add_presentation_chain(
220+ spec, size.width.as_int(), size.height.as_int(), 0, 0, chain);
221+ mir_surface_apply_spec(surface, spec);
222+ mir_surface_spec_release(spec);
223+
224+ MirBufferSync context;
225+ mir_connection_allocate_buffer(
226+ connection,
227+ size.width.as_int(), size.height.as_int(), pf, usage,
228+ buffer_callback, &context);
229+ ASSERT_TRUE(context.wait_for_buffer(10s));
230+ context.unavailable();
231+ mir_presentation_chain_submit_buffer(chain, context.buffer());
232+
233+ spec = mir_connection_create_spec_for_changes(connection);
234+ mir_surface_spec_add_buffer_stream(spec, 0, 0, stream);
235+ mir_surface_apply_spec(surface, spec);
236+ mir_surface_spec_release(spec);
237+ mir_presentation_chain_release(chain);
238+ mir_buffer_stream_swap_buffers_sync(stream);
239+
240+ ASSERT_TRUE(context.wait_for_buffer(10s));
241+
242+ mir_buffer_stream_release_sync(stream);
243+ mir_surface_release_sync(surface);
244+}
245+
246 TEST_F(PresentationChain, can_access_basic_buffer_properties)
247 {
248 MirBufferSync context;
249@@ -417,4 +465,7 @@
250
251 ASSERT_TRUE(another_context.wait_for_buffer(10s));
252 ASSERT_THAT(another_context.buffer(), Ne(nullptr));
253+
254+ mir_buffer_set_callback(context.buffer(), ignore_callback, nullptr);
255+ mir_buffer_set_callback(second_buffer_context.buffer(), ignore_callback, nullptr);
256 }
257
258=== modified file 'tests/integration-tests/test_buffer_scheduling.cpp'
259--- tests/integration-tests/test_buffer_scheduling.cpp 2016-08-16 19:34:28 +0000
260+++ tests/integration-tests/test_buffer_scheduling.cpp 2016-09-22 19:03:27 +0000
261@@ -453,6 +453,10 @@
262 vault.set_size(sz);
263 });
264 }
265+ ~ScheduledProducer()
266+ {
267+ ipc->on_client_bound_transfer([this](mp::BufferRequest&){});
268+ }
269
270 bool can_produce()
271 {
272
273=== modified file 'tests/unit-tests/client/test_mir_connection.cpp'
274--- tests/unit-tests/client/test_mir_connection.cpp 2016-06-28 12:18:18 +0000
275+++ tests/unit-tests/client/test_mir_connection.cpp 2016-09-22 19:03:27 +0000
276@@ -820,7 +820,7 @@
277 static_cast<MirPresentationChain*>(callback.resulting_chain)->rpc_id());
278
279 EXPECT_CALL(*mock_channel, buffer_stream_release(ReleaseRequestHasId(expected_request)))
280- .Times(0);
281+ .Times(1);
282
283 connection->release_presentation_chain(callback.resulting_chain);
284 }
285
286=== modified file 'tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp'
287--- tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2016-06-02 05:33:50 +0000
288+++ tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2016-09-22 19:03:27 +0000
289@@ -142,6 +142,7 @@
290 EXPECT_THAT(cbuffer1, Ne(cbuffer2));
291 arbiter.compositor_release(cbuffer2);
292 arbiter.compositor_release(cbuffer1);
293+ Mock::VerifyAndClearExpectations(&mock_map);
294 }
295
296 TEST_F(MultiMonitorArbiterWithAnyFrameGuarantee, compositor_buffer_syncs_to_fastest_compositor)
297@@ -394,6 +395,8 @@
298 arbiter.compositor_release(b4);
299 auto b6 = arbiter.compositor_acquire(&comp_id1);
300 arbiter.compositor_release(b6);
301+
302+ Mock::VerifyAndClearExpectations(&mock_map);
303 }
304
305 TEST_F(MultiMonitorArbiter, can_check_if_buffers_are_ready)
306@@ -458,6 +461,7 @@
307 EXPECT_THAT(b2, Eq(buffers[1]));
308 arbiter.compositor_release(b1);
309 arbiter.compositor_release(b2);
310+ Mock::VerifyAndClearExpectations(&mock_map);
311 }
312
313 TEST_F(MultiMonitorArbiter, will_release_buffer_in_nbuffers_2_starvation_scenario)
314@@ -513,6 +517,7 @@
315 EXPECT_THAT(b3, Eq(buffers[1]));
316 EXPECT_THAT(b4, Eq(buffers[1]));
317 EXPECT_THAT(b5, Eq(buffers[2]));
318+ Mock::VerifyAndClearExpectations(&mock_map);
319 }
320
321 TEST_F(MultiMonitorArbiter, can_advance_buffer_manually)
322@@ -532,3 +537,11 @@
323 auto b3 = arbiter.compositor_acquire(&comp_id1);
324 EXPECT_THAT(b3->id(), Eq(buffers[2]->id()));
325 }
326+
327+TEST_F(MultiMonitorArbiter, releases_buffer_on_destruction)
328+{
329+ mc::MultiMonitorArbiter arbiter{guarantee, mt::fake_shared(mock_map), mt::fake_shared(schedule)};
330+ EXPECT_CALL(mock_map, send_buffer(buffers[0]->id()));
331+ schedule.set_schedule({buffers[0]});
332+ arbiter.advance_schedule();
333+}
334
335=== modified file 'tests/unit-tests/compositor/test_stream.cpp'
336--- tests/unit-tests/compositor/test_stream.cpp 2016-05-04 01:48:16 +0000
337+++ tests/unit-tests/compositor/test_stream.cpp 2016-09-22 19:03:27 +0000
338@@ -123,6 +123,7 @@
339 cbuffers.push_back(stream.lock_compositor_buffer(this));
340 ASSERT_THAT(cbuffers, SizeIs(1));
341 EXPECT_THAT(cbuffers[0]->id(), Eq(buffers.back()->id()));
342+ Mock::VerifyAndClearExpectations(&mock_sink);
343 }
344
345 TEST_F(Stream, transitions_from_framedropping_to_queuing)
346@@ -325,6 +326,7 @@
347 Mock::VerifyAndClearExpectations(&mock_sink);
348 EXPECT_CALL(mock_sink, send_buffer(_,_,_));
349 framedrop_factory.trigger_policies();
350+ Mock::VerifyAndClearExpectations(&mock_sink);
351 }
352
353 TEST_F(Stream, doesnt_drop_the_only_frame_when_arbiter_has_none)
354@@ -334,6 +336,7 @@
355 EXPECT_CALL(mock_sink, send_buffer(_,_,_))
356 .Times(0);
357 framedrop_factory.trigger_policies();
358+ Mock::VerifyAndClearExpectations(&mock_sink);
359 }
360
361 TEST_F(Stream, doesnt_drop_the_latest_frame_with_a_longer_queue)
362@@ -347,6 +350,7 @@
363 EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[1]),_))
364 .Times(1);
365 framedrop_factory.trigger_policies();
366+ Mock::VerifyAndClearExpectations(&mock_sink);
367 }
368
369 TEST_F(Stream, doesnt_drop_the_latest_frame_with_a_2_buffer_queue)
370@@ -359,6 +363,7 @@
371 EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[1]),_))
372 .Times(0);
373 framedrop_factory.trigger_policies();
374+ Mock::VerifyAndClearExpectations(&mock_sink);
375 }
376
377 TEST_F(Stream, returns_buffers_to_client_when_told_to_bring_queue_up_to_date)
378@@ -371,4 +376,5 @@
379 EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[0]),_));
380 EXPECT_CALL(mock_sink, send_buffer(_,Ref(*buffers[1]),_));
381 stream.drop_old_buffers();
382+ Mock::VerifyAndClearExpectations(&mock_sink);
383 }

Subscribers

People subscribed via source and target branches