Skip to content

Commit 65ca15d

Browse files
a-sullyChromium LUCI CQ
authored and
Chromium LUCI CQ
committed
Speculative fix of CdmStorageTest.ParallelRead
As currently written, this test relies on Read() finishing asynchronously, since if the first Read() call finishes before the second one starts then both calls can pass (or fail). This CL uses TestFuture to ensure the second call is made before the first completes. Also proactively updates the ParallelWrite test to follow the same pattern, allowing us to clean up some helper code. Bug: 1302616 Change-Id: Ie8ab346a18db644c4ea8e451939b1f615abb840b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3537678 Reviewed-by: John Rummell <[email protected]> Commit-Queue: Austin Sullivan <[email protected]> Auto-Submit: Austin Sullivan <[email protected]> Cr-Commit-Position: refs/heads/main@{#983479}
1 parent 72315bb commit 65ca15d

File tree

1 file changed

+30
-92
lines changed

1 file changed

+30
-92
lines changed

content/browser/media/cdm_storage_impl_unittest.cc

+30-92
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "base/callback.h"
1111
#include "base/files/file.h"
1212
#include "base/logging.h"
13-
#include "base/run_loop.h"
1413
#include "base/test/test_future.h"
1514
#include "base/test/with_feature_override.h"
1615
#include "content/browser/media/media_license_manager.h"
@@ -50,36 +49,6 @@ void SimulateNavigation(RenderFrameHost** rfh, const GURL& url) {
5049
*rfh = navigation_simulator->GetFinalRenderFrameHost();
5150
}
5251

53-
// Helper that wraps a base::RunLoop and only quits the RunLoop
54-
// if the expected number of quit calls have happened.
55-
class RunLoopWithExpectedCount {
56-
public:
57-
RunLoopWithExpectedCount() = default;
58-
59-
RunLoopWithExpectedCount(const RunLoopWithExpectedCount&) = delete;
60-
RunLoopWithExpectedCount& operator=(const RunLoopWithExpectedCount&) = delete;
61-
62-
~RunLoopWithExpectedCount() { DCHECK_EQ(0, remaining_quit_calls_); }
63-
64-
void Run(int expected_quit_calls) {
65-
DCHECK_GT(expected_quit_calls, 0);
66-
DCHECK_EQ(remaining_quit_calls_, 0);
67-
remaining_quit_calls_ = expected_quit_calls;
68-
run_loop_ = std::make_unique<base::RunLoop>();
69-
run_loop_->Run();
70-
}
71-
72-
void Quit() {
73-
if (--remaining_quit_calls_ > 0)
74-
return;
75-
run_loop_->Quit();
76-
}
77-
78-
private:
79-
std::unique_ptr<base::RunLoop> run_loop_;
80-
int remaining_quit_calls_ = 0;
81-
};
82-
8352
} // namespace
8453

8554
class CdmStorageTest : public base::test::WithFeatureOverride,
@@ -159,23 +128,6 @@ class CdmStorageTest : public base::test::WithFeatureOverride,
159128
return status == CdmFile::Status::kSuccess;
160129
}
161130

162-
// Attempts to reads the contents of the previously opened |cdm_file| twice.
163-
// We don't really care about the data, just that 1 read succeeds and the
164-
// other fails.
165-
void ReadTwice(CdmFile* cdm_file,
166-
CdmFile::Status* status1,
167-
CdmFile::Status* status2) {
168-
DVLOG(3) << __func__;
169-
std::vector<uint8_t> data1;
170-
std::vector<uint8_t> data2;
171-
172-
cdm_file->Read(base::BindOnce(&CdmStorageTest::FileRead,
173-
base::Unretained(this), status1, &data1));
174-
cdm_file->Read(base::BindOnce(&CdmStorageTest::FileRead,
175-
base::Unretained(this), status2, &data2));
176-
RunAndWaitForResult(2);
177-
}
178-
179131
// Writes |data| to the previously opened |cdm_file|, replacing the contents
180132
// of the file. Returns true if successful, false otherwise.
181133
bool Write(CdmFile* cdm_file, const std::vector<uint8_t>& data) {
@@ -188,47 +140,9 @@ class CdmStorageTest : public base::test::WithFeatureOverride,
188140
return status == CdmFile::Status::kSuccess;
189141
}
190142

191-
// Attempts to write the contents of the previously opened |cdm_file| twice.
192-
// We don't really care about the data, just that 1 read succeeds and the
193-
// other fails.
194-
void WriteTwice(CdmFile* cdm_file,
195-
CdmFile::Status* status1,
196-
CdmFile::Status* status2) {
197-
DVLOG(3) << __func__;
198-
199-
cdm_file->Write({1, 2, 3}, base::BindOnce(&CdmStorageTest::FileWritten,
200-
base::Unretained(this), status1));
201-
cdm_file->Write({4, 5, 6}, base::BindOnce(&CdmStorageTest::FileWritten,
202-
base::Unretained(this), status2));
203-
RunAndWaitForResult(2);
204-
}
205-
206143
private:
207-
void FileRead(CdmFile::Status* status,
208-
std::vector<uint8_t>* data,
209-
CdmFile::Status actual_status,
210-
const std::vector<uint8_t>& actual_data) {
211-
DVLOG(3) << __func__;
212-
*status = actual_status;
213-
*data = actual_data;
214-
run_loop_with_count_->Quit();
215-
}
216-
217-
void FileWritten(CdmFile::Status* status, CdmFile::Status actual_status) {
218-
DVLOG(3) << __func__;
219-
*status = actual_status;
220-
run_loop_with_count_->Quit();
221-
}
222-
223-
// Start running and allow the asynchronous IO operations to complete.
224-
void RunAndWaitForResult(int expected_quit_calls) {
225-
run_loop_with_count_ = std::make_unique<RunLoopWithExpectedCount>();
226-
run_loop_with_count_->Run(expected_quit_calls);
227-
}
228-
229144
RenderFrameHost* rfh_ = nullptr;
230145
mojo::Remote<CdmStorage> cdm_storage_;
231-
std::unique_ptr<RunLoopWithExpectedCount> run_loop_with_count_;
232146
};
233147

234148
// TODO(crbug.com/1231162): Make this a non-parameterized test suite once we no
@@ -349,9 +263,22 @@ TEST_P(CdmStorageTest, ParallelRead) {
349263
EXPECT_TRUE(Open(kFileName, cdm_file));
350264
EXPECT_TRUE(cdm_file.is_bound());
351265

352-
CdmFile::Status status1;
353-
CdmFile::Status status2;
354-
ReadTwice(cdm_file.get(), &status1, &status2);
266+
// Attempts to reads the contents of the previously opened |cdm_file| twice.
267+
// We don't really care about the data, just that 1 read succeeds and the
268+
// other fails.
269+
base::test::TestFuture<CdmFile::Status, std::vector<uint8_t>> future1;
270+
base::test::TestFuture<CdmFile::Status, std::vector<uint8_t>> future2;
271+
272+
cdm_file->Read(
273+
future1.GetCallback<CdmFile::Status, const std::vector<uint8_t>&>());
274+
cdm_file->Read(
275+
future2.GetCallback<CdmFile::Status, const std::vector<uint8_t>&>());
276+
277+
EXPECT_TRUE(future1.Wait());
278+
EXPECT_TRUE(future2.Wait());
279+
280+
CdmFile::Status status1 = future1.Get<0>();
281+
CdmFile::Status status2 = future2.Get<0>();
355282

356283
// One call should succeed, one should fail.
357284
EXPECT_TRUE((status1 == CdmFile::Status::kSuccess &&
@@ -367,9 +294,20 @@ TEST_P(CdmStorageTest, ParallelWrite) {
367294
EXPECT_TRUE(Open(kFileName, cdm_file));
368295
EXPECT_TRUE(cdm_file.is_bound());
369296

370-
CdmFile::Status status1;
371-
CdmFile::Status status2;
372-
WriteTwice(cdm_file.get(), &status1, &status2);
297+
// Attempts to write the contents of the previously opened |cdm_file| twice.
298+
// We don't really care about the data, just that 1 write succeeds and the
299+
// other fails.
300+
base::test::TestFuture<CdmFile::Status> future1;
301+
base::test::TestFuture<CdmFile::Status> future2;
302+
303+
cdm_file->Write({1, 2, 3}, future1.GetCallback());
304+
cdm_file->Write({4, 5, 6}, future2.GetCallback());
305+
306+
EXPECT_TRUE(future1.Wait());
307+
EXPECT_TRUE(future2.Wait());
308+
309+
CdmFile::Status status1 = future1.Get();
310+
CdmFile::Status status2 = future2.Get();
373311

374312
// One call should succeed, one should fail.
375313
EXPECT_TRUE((status1 == CdmFile::Status::kSuccess &&

0 commit comments

Comments
 (0)