summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 18:23:49 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 18:23:49 +0000
commitb1dc1dec10e03ca7fdf4219d7059dfc07973811a (patch)
tree87c44dfa015a6139daac9d027f906d9d6581d051 /media/base
parent68a983963a8ef1718400bb7a7f177f5a26ae4656 (diff)
downloadchromium_src-b1dc1dec10e03ca7fdf4219d7059dfc07973811a.zip
chromium_src-b1dc1dec10e03ca7fdf4219d7059dfc07973811a.tar.gz
chromium_src-b1dc1dec10e03ca7fdf4219d7059dfc07973811a.tar.bz2
Refactor FFmpegDemuxerTest to use gmock and eliminate flakiness.
This eliminates all final traces of the old global-functions-and-variables style of mocking, which was a massive headache to maintain and verify correctness. No new tests have been added, however gmock creates much stronger assertions for the tests themselves. I also made FFmpegDemuxerTest a friend of FFmpegDemuxer to let tests verify that all tasks on the internal demuxing thread have completed. BUG=13933 TEST=FFmpegDemuxerTest should more awesome and less flaky Review URL: http://codereview.chromium.org/126306 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18833 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r--media/base/mock_ffmpeg.cc71
-rw-r--r--media/base/mock_ffmpeg.h78
2 files changed, 148 insertions, 1 deletions
diff --git a/media/base/mock_ffmpeg.cc b/media/base/mock_ffmpeg.cc
index 4e9fc03..b1de0c4 100644
--- a/media/base/mock_ffmpeg.cc
+++ b/media/base/mock_ffmpeg.cc
@@ -11,6 +11,24 @@ namespace media {
MockFFmpeg* MockFFmpeg::instance_ = NULL;
+MockFFmpeg::MockFFmpeg()
+ : outstanding_packets_(0) {
+}
+
+MockFFmpeg::~MockFFmpeg() {
+ CHECK(!outstanding_packets_)
+ << "MockFFmpeg destroyed with outstanding packets";
+}
+
+void MockFFmpeg::inc_outstanding_packets() {
+ ++outstanding_packets_;
+}
+
+void MockFFmpeg::dec_outstanding_packets() {
+ CHECK(outstanding_packets_ > 0);
+ --outstanding_packets_;
+}
+
// static
void MockFFmpeg::set(MockFFmpeg* instance) {
instance_ = instance;
@@ -21,6 +39,13 @@ MockFFmpeg* MockFFmpeg::get() {
return instance_;
}
+// static
+void MockFFmpeg::DestructPacket(AVPacket* packet) {
+ delete [] packet->data;
+ packet->data = NULL;
+ packet->size = 0;
+}
+
// FFmpeg stubs that delegate to the FFmpegMock instance.
extern "C" {
@@ -55,6 +80,52 @@ void av_init_packet(AVPacket* pkt) {
NOTREACHED();
}
+int av_open_input_file(AVFormatContext** format, const char* filename,
+ AVInputFormat* input_format, int buffer_size,
+ AVFormatParameters* parameters) {
+ return media::MockFFmpeg::get()->AVOpenInputFile(format, filename,
+ input_format, buffer_size,
+ parameters);
+}
+
+int av_find_stream_info(AVFormatContext* format) {
+ return media::MockFFmpeg::get()->AVFindStreamInfo(format);
+}
+
+int64 av_rescale_q(int64 a, AVRational bq, AVRational cq) {
+ // Because this is a math function there's little point in mocking it, so we
+ // implement a cheap version that's capable of overflowing.
+ int64 num = bq.num * cq.den;
+ int64 den = cq.num * bq.den;
+ return a * num / den;
+}
+
+void av_free_packet(AVPacket* packet) {
+ media::MockFFmpeg::get()->AVFreePacket(packet);
+}
+
+int av_new_packet(AVPacket* packet, int size) {
+ return media::MockFFmpeg::get()->AVNewPacket(packet, size);
+}
+
+void av_free(void* ptr) {
+ // Freeing NULL pointers are valid, but they aren't interesting from a mock
+ // perspective.
+ if (ptr) {
+ media::MockFFmpeg::get()->AVFree(ptr);
+ }
+}
+
+int av_read_frame(AVFormatContext* format, AVPacket* packet) {
+ return media::MockFFmpeg::get()->AVReadFrame(format, packet);
+}
+
+int av_seek_frame(AVFormatContext *format, int stream_index, int64_t timestamp,
+ int flags) {
+ return media::MockFFmpeg::get()->AVSeekFrame(format, stream_index, timestamp,
+ flags);
+}
+
} // extern "C"
} // namespace media
diff --git a/media/base/mock_ffmpeg.h b/media/base/mock_ffmpeg.h
index 711cf15..597898e 100644
--- a/media/base/mock_ffmpeg.h
+++ b/media/base/mock_ffmpeg.h
@@ -7,25 +7,101 @@
// TODO(scherkus): See if we can remove ffmpeg_common from this file.
#include "media/filters/ffmpeg_common.h"
-
#include "testing/gmock/include/gmock/gmock.h"
namespace media {
class MockFFmpeg {
public:
+ MockFFmpeg();
+ ~MockFFmpeg();
+
MOCK_METHOD1(AVCodecFindDecoder, AVCodec*(enum CodecID id));
MOCK_METHOD2(AVCodecOpen, int(AVCodecContext* avctx, AVCodec* codec));
MOCK_METHOD2(AVCodecThreadInit, int(AVCodecContext* avctx, int threads));
+ MOCK_METHOD5(AVOpenInputFile, int(AVFormatContext** format,
+ const char* filename,
+ AVInputFormat* input_format,
+ int buffer_size,
+ AVFormatParameters* parameters));
+ MOCK_METHOD1(AVFindStreamInfo, int(AVFormatContext* format));
+ MOCK_METHOD2(AVReadFrame, int(AVFormatContext* format, AVPacket* packet));
+ MOCK_METHOD4(AVSeekFrame, int(AVFormatContext *format,
+ int stream_index,
+ int64_t timestamp,
+ int flags));
+
+ MOCK_METHOD2(AVNewPacket, int(AVPacket* packet, int size));
+ MOCK_METHOD1(AVFree, void(void* ptr));
+ MOCK_METHOD1(AVFreePacket, void(AVPacket* packet));
+
+ // Used for verifying check points during tests.
+ MOCK_METHOD1(CheckPoint, void(int id));
+
// Setter/getter for the global instance of MockFFmpeg.
static void set(MockFFmpeg* instance);
static MockFFmpeg* get();
+ // AVPacket destructor for packets allocated by av_new_packet().
+ static void DestructPacket(AVPacket* packet);
+
+ // Modifies the number of outstanding packets.
+ void inc_outstanding_packets();
+ void dec_outstanding_packets();
+
private:
static MockFFmpeg* instance_;
+
+ // Tracks the number of packets allocated by calls to av_read_frame() and
+ // av_free_packet(). We crash the unit test if this is not zero at time of
+ // destruction.
+ int outstanding_packets_;
};
+// Used for simulating av_read_frame().
+ACTION_P3(CreatePacket, stream_index, data, size) {
+ // Confirm we're dealing with AVPacket so we can safely const_cast<>.
+ ::testing::StaticAssertTypeEq<AVPacket*, arg1_type>();
+ memset(arg1, 0, sizeof(*arg1));
+ arg1->stream_index = stream_index;
+ arg1->data = const_cast<uint8*>(data);
+ arg1->size = size;
+
+ // Increment number of packets allocated.
+ MockFFmpeg::get()->inc_outstanding_packets();
+
+ return 0;
+}
+
+// Used for simulating av_new_packet().
+ACTION(NewPacket) {
+ ::testing::StaticAssertTypeEq<AVPacket*, arg0_type>();
+ int size = arg1;
+ memset(arg0, 0, sizeof(*arg0));
+ arg0->data = new uint8[size];
+ arg0->size = size;
+ arg0->destruct = &MockFFmpeg::DestructPacket;
+
+ // Increment number of packets allocated.
+ MockFFmpeg::get()->inc_outstanding_packets();
+
+ return 0;
+}
+
+// Used for simulating av_free_packet().
+ACTION(FreePacket) {
+ ::testing::StaticAssertTypeEq<AVPacket*, arg0_type>();
+
+ // Call the destructor if present, such as the one assigned in NewPacket().
+ if (arg0->destruct) {
+ arg0->destruct(arg0);
+ }
+
+ // Decrement number of packets allocated.
+ MockFFmpeg::get()->dec_outstanding_packets();
+}
+
} // namespace media
#endif // MEDIA_BASE_MOCK_FFMPEG_H_