blob: 1a3d6186ffc76febb491bc2c5bbe24db2bcde5e9 [file] [log] [blame]
// // Copyright 2018 The Fuchsia 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 "garnet/bin/mediaplayer/demux/reader_cache.h"
#include "gtest/gtest.h"
namespace media_player {
namespace {
class FakeReader : public Reader {
public:
FakeReader() {}
void Describe(DescribeCallback callback) override {
callback(Result::kOk, 500000, true);
}
void ReadAt(size_t position, uint8_t* buffer, size_t bytes_to_read,
ReadAtCallback callback) override {
callback_ = std::move(callback);
bytes_to_read_ = bytes_to_read;
}
std::pair<ReadAtCallback, size_t> GetCallback() {
return {std::move(callback_), bytes_to_read_};
}
private:
ReadAtCallback callback_;
size_t bytes_to_read_;
};
TEST(ReaderCache, MTWN214Repro) {
auto fake_reader = std::make_shared<FakeReader>();
auto under_test = ReaderCache::Create(fake_reader);
uint8_t dest[800] = {0};
// Set up a load and leave it hanging.
under_test->ReadAt(0, dest, 100, [](Result result, size_t bytes_read) {});
auto [first_callback, first_bytes] = fake_reader->GetCallback();
// Start a new load so that ReadAt queues a recursive call on the upstream
// reader callback incident.
under_test->ReadAt(101, dest, 300, [](Result result, size_t bytes_read) {});
under_test->ReadAt(300, dest, 600, [](Result result, size_t bytes_read) {});
// Finish the first load, so that the reader callback incident calls itself. It
// will not escape before hitting the stack limit because we aren't finishing
// any more loads in this test.
//
// To pass, this just needs to not crash.
first_callback(Result::kOk, 100);
}
} // namespace
} // namespace media_player