Add tests for SimpleMpdNotifier
- Add Mock{MpdBuilder, AdaptationSet, Representation}. Change-Id: I7444e0fa955abedded83809fbb8b20ea6357e78a
This commit is contained in:
parent
fe851f692b
commit
817b2a3a19
|
@ -0,0 +1,34 @@
|
||||||
|
#include "packager/mpd/base/mock_mpd_builder.h"
|
||||||
|
|
||||||
|
#include "packager/mpd/base/media_info.pb.h"
|
||||||
|
|
||||||
|
namespace edash_packager {
|
||||||
|
namespace {
|
||||||
|
const uint32_t kAnyAdaptationSetId = 1;
|
||||||
|
const char kEmptyLang[] = "";
|
||||||
|
const MpdOptions kDefaultMpdOptions;
|
||||||
|
const MpdBuilder::MpdType kDefaultMpdType = MpdBuilder::kStatic;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Doesn't matter what values get passed to the super class' constructor.
|
||||||
|
// All methods used for testing should be mocked.
|
||||||
|
MockMpdBuilder::MockMpdBuilder(MpdType type)
|
||||||
|
: MpdBuilder(type, kDefaultMpdOptions) {}
|
||||||
|
MockMpdBuilder::~MockMpdBuilder() {}
|
||||||
|
|
||||||
|
MockAdaptationSet::MockAdaptationSet()
|
||||||
|
: AdaptationSet(kAnyAdaptationSetId,
|
||||||
|
kEmptyLang,
|
||||||
|
kDefaultMpdOptions,
|
||||||
|
kDefaultMpdType,
|
||||||
|
&sequence_counter_) {}
|
||||||
|
MockAdaptationSet::~MockAdaptationSet() {}
|
||||||
|
|
||||||
|
MockRepresentation::MockRepresentation(uint32_t representation_id)
|
||||||
|
: Representation(MediaInfo(),
|
||||||
|
kDefaultMpdOptions,
|
||||||
|
representation_id,
|
||||||
|
scoped_ptr<RepresentationStateChangeListener>()) {}
|
||||||
|
MockRepresentation::~MockRepresentation() {}
|
||||||
|
|
||||||
|
} // namespace edash_packager
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#ifndef MPD_BASE_MOCK_MPD_BUILDER_H_
|
||||||
|
#define MPD_BASE_MOCK_MPD_BUILDER_H_
|
||||||
|
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
#include "packager/base/compiler_specific.h"
|
||||||
|
#include "packager/mpd/base/content_protection_element.h"
|
||||||
|
#include "packager/mpd/base/mpd_builder.h"
|
||||||
|
|
||||||
|
namespace edash_packager {
|
||||||
|
|
||||||
|
class MockMpdBuilder : public MpdBuilder {
|
||||||
|
public:
|
||||||
|
// type indicates whether the MPD should be for VOD or live content (kStatic
|
||||||
|
// for VOD profile, or kDynamic for live profile).
|
||||||
|
explicit MockMpdBuilder(MpdType type);
|
||||||
|
virtual ~MockMpdBuilder() OVERRIDE;
|
||||||
|
|
||||||
|
MOCK_METHOD1(AddAdaptationSet, AdaptationSet*(const std::string& lang));
|
||||||
|
MOCK_METHOD1(ToString, bool(std::string* output));
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockAdaptationSet : public AdaptationSet {
|
||||||
|
public:
|
||||||
|
MockAdaptationSet();
|
||||||
|
virtual ~MockAdaptationSet() OVERRIDE;
|
||||||
|
|
||||||
|
MOCK_METHOD1(AddRepresentation, Representation*(const MediaInfo& media_info));
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only for constructing the super class. Not used for testing.
|
||||||
|
base::AtomicSequenceNumber sequence_counter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockRepresentation : public Representation {
|
||||||
|
public:
|
||||||
|
// |representation_id| is the numeric ID for the <Representation>.
|
||||||
|
explicit MockRepresentation(uint32_t representation_id);
|
||||||
|
virtual ~MockRepresentation() OVERRIDE;
|
||||||
|
|
||||||
|
MOCK_METHOD1(AddContentProtectionElement,
|
||||||
|
void(const ContentProtectionElement& element));
|
||||||
|
MOCK_METHOD3(AddNewSegment,
|
||||||
|
void(uint64_t start_time, uint64_t duration, uint64_t size));
|
||||||
|
MOCK_METHOD1(SetSampleDuration, void(uint32_t sample_duration));
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace edash_packager
|
||||||
|
|
||||||
|
#endif // MPD_BASE_MOCK_MPD_BUILDER_H_
|
|
@ -391,7 +391,6 @@ bool MpdBuilder::ToString(std::string* output) {
|
||||||
DCHECK(output);
|
DCHECK(output);
|
||||||
return WriteMpdToOutput(output);
|
return WriteMpdToOutput(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputType>
|
template <typename OutputType>
|
||||||
bool MpdBuilder::WriteMpdToOutput(OutputType* output) {
|
bool MpdBuilder::WriteMpdToOutput(OutputType* output) {
|
||||||
static LibXmlInitializer lib_xml_initializer;
|
static LibXmlInitializer lib_xml_initializer;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
// declarations.
|
// declarations.
|
||||||
// http://goo.gl/UrsSlF
|
// http://goo.gl/UrsSlF
|
||||||
//
|
//
|
||||||
|
/// All the methods that are virtual are virtual for mocking.
|
||||||
/// NOTE: Inclusion of this module will cause xmlInitParser and xmlCleanupParser
|
/// NOTE: Inclusion of this module will cause xmlInitParser and xmlCleanupParser
|
||||||
/// to be called at static initialization / deinitialization time.
|
/// to be called at static initialization / deinitialization time.
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ class MpdBuilder {
|
||||||
/// @param type indicates whether the MPD should be for VOD or live content
|
/// @param type indicates whether the MPD should be for VOD or live content
|
||||||
/// (kStatic for VOD profile, or kDynamic for live profile).
|
/// (kStatic for VOD profile, or kDynamic for live profile).
|
||||||
MpdBuilder(MpdType type, const MpdOptions& mpd_options);
|
MpdBuilder(MpdType type, const MpdOptions& mpd_options);
|
||||||
~MpdBuilder();
|
virtual ~MpdBuilder();
|
||||||
|
|
||||||
/// Add <BaseURL> entry to the MPD.
|
/// Add <BaseURL> entry to the MPD.
|
||||||
/// @param base_url URL for <BaseURL> entry.
|
/// @param base_url URL for <BaseURL> entry.
|
||||||
|
@ -74,7 +75,7 @@ class MpdBuilder {
|
||||||
/// @param lang is the language of the AdaptationSet. This can be empty for
|
/// @param lang is the language of the AdaptationSet. This can be empty for
|
||||||
/// videos, for example.
|
/// videos, for example.
|
||||||
/// @return The new adaptation set, which is owned by this instance.
|
/// @return The new adaptation set, which is owned by this instance.
|
||||||
AdaptationSet* AddAdaptationSet(const std::string& lang);
|
virtual AdaptationSet* AddAdaptationSet(const std::string& lang);
|
||||||
|
|
||||||
/// Write the MPD to specified file.
|
/// Write the MPD to specified file.
|
||||||
/// @param[out] output_file is MPD destination. output_file will be
|
/// @param[out] output_file is MPD destination. output_file will be
|
||||||
|
@ -85,10 +86,10 @@ class MpdBuilder {
|
||||||
/// Writes the MPD to the given string.
|
/// Writes the MPD to the given string.
|
||||||
/// @param[out] output is an output string where the MPD gets written.
|
/// @param[out] output is an output string where the MPD gets written.
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
bool ToString(std::string* output);
|
virtual bool ToString(std::string* output);
|
||||||
|
|
||||||
/// @return The mpd type.
|
/// @return The mpd type.
|
||||||
MpdType type() { return type_; }
|
MpdType type() const { return type_; }
|
||||||
|
|
||||||
/// Adjusts the fields of MediaInfo so that paths are relative to the
|
/// Adjusts the fields of MediaInfo so that paths are relative to the
|
||||||
/// specified MPD path.
|
/// specified MPD path.
|
||||||
|
@ -168,14 +169,14 @@ class AdaptationSet {
|
||||||
kRoleDub
|
kRoleDub
|
||||||
};
|
};
|
||||||
|
|
||||||
~AdaptationSet();
|
virtual ~AdaptationSet();
|
||||||
|
|
||||||
/// Create a Representation instance using @a media_info.
|
/// Create a Representation instance using @a media_info.
|
||||||
/// @param media_info is a MediaInfo object used to initialize the returned
|
/// @param media_info is a MediaInfo object used to initialize the returned
|
||||||
/// Representation instance.
|
/// Representation instance.
|
||||||
/// @return On success, returns a pointer to Representation. Otherwise returns
|
/// @return On success, returns a pointer to Representation. Otherwise returns
|
||||||
/// NULL. The returned pointer is owned by the AdaptationSet instance.
|
/// NULL. The returned pointer is owned by the AdaptationSet instance.
|
||||||
Representation* AddRepresentation(const MediaInfo& media_info);
|
virtual Representation* AddRepresentation(const MediaInfo& media_info);
|
||||||
|
|
||||||
/// Add a ContenProtection element to the adaptation set.
|
/// Add a ContenProtection element to the adaptation set.
|
||||||
/// AdaptationSet does not add <ContentProtection> elements
|
/// AdaptationSet does not add <ContentProtection> elements
|
||||||
|
@ -234,6 +235,20 @@ class AdaptationSet {
|
||||||
uint64_t start_time,
|
uint64_t start_time,
|
||||||
uint64_t duration);
|
uint64_t duration);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// @param adaptation_set_id is an ID number for this AdaptationSet.
|
||||||
|
/// @param lang is the language of this AdaptationSet. Mainly relevant for
|
||||||
|
/// audio.
|
||||||
|
/// @param mpd_options is the options for this MPD.
|
||||||
|
/// @param mpd_type is the type of this MPD.
|
||||||
|
/// @param representation_counter is a Counter for assigning ID numbers to
|
||||||
|
/// Representation. It can not be NULL.
|
||||||
|
AdaptationSet(uint32_t adaptation_set_id,
|
||||||
|
const std::string& lang,
|
||||||
|
const MpdOptions& mpd_options,
|
||||||
|
MpdBuilder::MpdType mpd_type,
|
||||||
|
base::AtomicSequenceNumber* representation_counter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// kSegmentAlignmentUnknown means that it is uncertain if the
|
// kSegmentAlignmentUnknown means that it is uncertain if the
|
||||||
// (sub)segments are aligned or not.
|
// (sub)segments are aligned or not.
|
||||||
|
@ -257,6 +272,7 @@ class AdaptationSet {
|
||||||
typedef std::map<uint32_t, std::list<uint64_t> > RepresentationTimeline;
|
typedef std::map<uint32_t, std::list<uint64_t> > RepresentationTimeline;
|
||||||
|
|
||||||
friend class MpdBuilder;
|
friend class MpdBuilder;
|
||||||
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckAdaptationSetId);
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckAdaptationSetId);
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest,
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest,
|
||||||
CheckAdaptationSetVideoContentType);
|
CheckAdaptationSetVideoContentType);
|
||||||
|
@ -269,19 +285,6 @@ class AdaptationSet {
|
||||||
FRIEND_TEST_ALL_PREFIXES(StaticMpdBuilderTest, ForceSetSubSegmentAlignment);
|
FRIEND_TEST_ALL_PREFIXES(StaticMpdBuilderTest, ForceSetSubSegmentAlignment);
|
||||||
FRIEND_TEST_ALL_PREFIXES(DynamicMpdBuilderTest, SegmentAlignment);
|
FRIEND_TEST_ALL_PREFIXES(DynamicMpdBuilderTest, SegmentAlignment);
|
||||||
|
|
||||||
/// @param adaptation_set_id is an ID number for this AdaptationSet.
|
|
||||||
/// @param lang is the language of this AdaptationSet. Mainly relevant for
|
|
||||||
/// audio.
|
|
||||||
/// @param mpd_options is the options for this MPD.
|
|
||||||
/// @param mpd_type is the type of this MPD.
|
|
||||||
/// @param representation_counter is a Counter for assigning ID numbers to
|
|
||||||
/// Representation. It can not be NULL.
|
|
||||||
AdaptationSet(uint32_t adaptation_set_id,
|
|
||||||
const std::string& lang,
|
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
MpdBuilder::MpdType mpd_type,
|
|
||||||
base::AtomicSequenceNumber* representation_counter);
|
|
||||||
|
|
||||||
// Gets the earliest, normalized segment timestamp. Returns true if
|
// Gets the earliest, normalized segment timestamp. Returns true if
|
||||||
// successful, false otherwise.
|
// successful, false otherwise.
|
||||||
bool GetEarliestTimestamp(double* timestamp_seconds);
|
bool GetEarliestTimestamp(double* timestamp_seconds);
|
||||||
|
@ -374,7 +377,7 @@ class RepresentationStateChangeListener {
|
||||||
/// well as optional ContentProtection elements for that stream.
|
/// well as optional ContentProtection elements for that stream.
|
||||||
class Representation {
|
class Representation {
|
||||||
public:
|
public:
|
||||||
~Representation();
|
virtual ~Representation();
|
||||||
|
|
||||||
/// Tries to initialize the instance. If this does not succeed, the instance
|
/// Tries to initialize the instance. If this does not succeed, the instance
|
||||||
/// should not be used.
|
/// should not be used.
|
||||||
|
@ -391,7 +394,8 @@ class Representation {
|
||||||
/// If @a element has {value, schemeIdUri} set and has
|
/// If @a element has {value, schemeIdUri} set and has
|
||||||
/// {“value”, “schemeIdUri”} as key for @a additional_attributes,
|
/// {“value”, “schemeIdUri”} as key for @a additional_attributes,
|
||||||
/// then the former is used.
|
/// then the former is used.
|
||||||
void AddContentProtectionElement(const ContentProtectionElement& element);
|
virtual void AddContentProtectionElement(
|
||||||
|
const ContentProtectionElement& element);
|
||||||
|
|
||||||
/// Add a media (sub)segment to the representation.
|
/// Add a media (sub)segment to the representation.
|
||||||
/// AdaptationSet@{subSegmentAlignment,segmentAlignment} cannot be set
|
/// AdaptationSet@{subSegmentAlignment,segmentAlignment} cannot be set
|
||||||
|
@ -401,14 +405,16 @@ class Representation {
|
||||||
/// @param duration is the duration of the segment, in units of the stream's
|
/// @param duration is the duration of the segment, in units of the stream's
|
||||||
/// time scale.
|
/// time scale.
|
||||||
/// @param size of the segment in bytes.
|
/// @param size of the segment in bytes.
|
||||||
void AddNewSegment(uint64_t start_time, uint64_t duration, uint64_t size);
|
virtual void AddNewSegment(uint64_t start_time,
|
||||||
|
uint64_t duration,
|
||||||
|
uint64_t size);
|
||||||
|
|
||||||
/// Set the sample duration of this Representation.
|
/// Set the sample duration of this Representation.
|
||||||
/// In most cases, the sample duration is not available right away. This
|
/// In most cases, the sample duration is not available right away. This
|
||||||
/// allows setting the sample duration after the Representation has been
|
/// allows setting the sample duration after the Representation has been
|
||||||
/// initialized.
|
/// initialized.
|
||||||
/// @param sample_duration is the duration of a sample.
|
/// @param sample_duration is the duration of a sample.
|
||||||
void SetSampleDuration(uint32_t sample_duration);
|
virtual void SetSampleDuration(uint32_t sample_duration);
|
||||||
|
|
||||||
/// @return Copy of <Representation>.
|
/// @return Copy of <Representation>.
|
||||||
xml::ScopedXmlPtr<xmlNode>::type GetXml();
|
xml::ScopedXmlPtr<xmlNode>::type GetXml();
|
||||||
|
@ -416,18 +422,7 @@ class Representation {
|
||||||
/// @return ID number for <Representation>.
|
/// @return ID number for <Representation>.
|
||||||
uint32_t id() const { return id_; }
|
uint32_t id() const { return id_; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
friend class AdaptationSet;
|
|
||||||
// TODO(rkuroiwa): Consider defining a public factory method that constructs
|
|
||||||
// and Init()s, at least for testing.
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, ValidMediaInfo);
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, InvalidMediaInfo);
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckVideoInfoReflectedInXml);
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckRepresentationId);
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, SetSampleDuration);
|
|
||||||
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest,
|
|
||||||
RepresentationStateChangeListener);
|
|
||||||
|
|
||||||
/// @param media_info is a MediaInfo containing information on the media.
|
/// @param media_info is a MediaInfo containing information on the media.
|
||||||
/// @a media_info.bandwidth is required for 'static' profile. If @a
|
/// @a media_info.bandwidth is required for 'static' profile. If @a
|
||||||
/// media_info.bandwidth is not present in 'dynamic' profile, this
|
/// media_info.bandwidth is not present in 'dynamic' profile, this
|
||||||
|
@ -442,6 +437,19 @@ class Representation {
|
||||||
uint32_t representation_id,
|
uint32_t representation_id,
|
||||||
scoped_ptr<RepresentationStateChangeListener> state_change_listener);
|
scoped_ptr<RepresentationStateChangeListener> state_change_listener);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class AdaptationSet;
|
||||||
|
|
||||||
|
// TODO(rkuroiwa): Consider defining a public factory method that constructs
|
||||||
|
// and Init()s, at least for testing.
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, ValidMediaInfo);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, InvalidMediaInfo);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckVideoInfoReflectedInXml);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, CheckRepresentationId);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest, SetSampleDuration);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CommonMpdBuilderTest,
|
||||||
|
RepresentationStateChangeListener);
|
||||||
|
|
||||||
bool AddLiveInfo(xml::RepresentationXmlNode* representation);
|
bool AddLiveInfo(xml::RepresentationXmlNode* representation);
|
||||||
|
|
||||||
// Returns true if |media_info_| has required fields to generate a valid
|
// Returns true if |media_info_| has required fields to generate a valid
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "packager/base/gtest_prod_util.h"
|
||||||
#include "packager/base/memory/scoped_ptr.h"
|
#include "packager/base/memory/scoped_ptr.h"
|
||||||
#include "packager/base/synchronization/lock.h"
|
#include "packager/base/synchronization/lock.h"
|
||||||
#include "packager/mpd/base/mpd_notifier.h"
|
#include "packager/mpd/base/mpd_notifier.h"
|
||||||
|
@ -20,6 +21,7 @@ namespace edash_packager {
|
||||||
class AdaptationSet;
|
class AdaptationSet;
|
||||||
class MpdBuilder;
|
class MpdBuilder;
|
||||||
class Representation;
|
class Representation;
|
||||||
|
class SimpleMpdNotifierTest;
|
||||||
|
|
||||||
struct MpdOptions;
|
struct MpdOptions;
|
||||||
|
|
||||||
|
@ -50,6 +52,18 @@ class SimpleMpdNotifier : public MpdNotifier {
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend SimpleMpdNotifierTest;
|
||||||
|
|
||||||
|
// Testing only method. Returns a pointer to MpdBuilder.
|
||||||
|
MpdBuilder* MpdBuilderForTesting() const {
|
||||||
|
return mpd_builder_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing only method. Sets mpd_builder_.
|
||||||
|
void SetMpdBuilderForTesting(scoped_ptr<MpdBuilder> mpd_builder) {
|
||||||
|
mpd_builder_ = mpd_builder.Pass();
|
||||||
|
}
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
kUnknown,
|
kUnknown,
|
||||||
kVideo,
|
kVideo,
|
||||||
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "packager/base/file_util.h"
|
||||||
|
#include "packager/base/files/file_path.h"
|
||||||
|
#include "packager/mpd/base/mock_mpd_builder.h"
|
||||||
|
#include "packager/mpd/base/mpd_builder.h"
|
||||||
|
#include "packager/mpd/base/mpd_options.h"
|
||||||
|
#include "packager/mpd/base/simple_mpd_notifier.h"
|
||||||
|
#include "packager/mpd/test/mpd_builder_test_helper.h"
|
||||||
|
|
||||||
|
namespace edash_packager {
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::Return;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const char kValidMediaInfo[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: 'avc1'\n"
|
||||||
|
" width: 1280\n"
|
||||||
|
" height: 720\n"
|
||||||
|
" time_scale: 10\n"
|
||||||
|
" frame_duration: 10\n"
|
||||||
|
" pixel_width: 1\n"
|
||||||
|
" pixel_height: 1\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class SimpleMpdNotifierTest
|
||||||
|
: public ::testing::TestWithParam<MpdBuilder::MpdType> {
|
||||||
|
protected:
|
||||||
|
SimpleMpdNotifierTest()
|
||||||
|
: default_mock_adaptation_set_(new MockAdaptationSet()) {}
|
||||||
|
|
||||||
|
virtual void SetUp() OVERRIDE {
|
||||||
|
ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path_));
|
||||||
|
output_path_ = temp_file_path_.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() OVERRIDE {
|
||||||
|
base::DeleteFile(temp_file_path_, false /* non recursive, just 1 file */);
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_ptr<MockMpdBuilder> StaticMpdBuilderMock() {
|
||||||
|
return make_scoped_ptr(new MockMpdBuilder(MpdBuilder::kStatic));
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_ptr<MockMpdBuilder> DynamicMpdBuilderMock() {
|
||||||
|
return make_scoped_ptr(new MockMpdBuilder(MpdBuilder::kDynamic));
|
||||||
|
}
|
||||||
|
|
||||||
|
MpdBuilder::MpdType GetMpdBuilderType(const SimpleMpdNotifier& notifier) {
|
||||||
|
return notifier.MpdBuilderForTesting()->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMpdBuilder(SimpleMpdNotifier* notifier,
|
||||||
|
scoped_ptr<MpdBuilder> mpd_builder) {
|
||||||
|
notifier->SetMpdBuilderForTesting(mpd_builder.Pass());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use output_path_ for specifying the MPD output path so that
|
||||||
|
// SimpleMpdNotifier::WriteMpdToFile() doesn't crash.
|
||||||
|
std::string output_path_;
|
||||||
|
const MpdOptions empty_mpd_option_;
|
||||||
|
const std::vector<std::string> empty_base_urls_;
|
||||||
|
|
||||||
|
// Default AdaptationSet mock.
|
||||||
|
scoped_ptr<MockAdaptationSet> default_mock_adaptation_set_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::FilePath temp_file_path_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Verify that it creates the correct MpdBuilder type using DashProfile passed
|
||||||
|
// to the constructor.
|
||||||
|
TEST_F(SimpleMpdNotifierTest, CreateCorrectMpdBuilderType) {
|
||||||
|
SimpleMpdNotifier on_demand_notifier(kOnDemandProfile, empty_mpd_option_,
|
||||||
|
empty_base_urls_, output_path_);
|
||||||
|
EXPECT_TRUE(on_demand_notifier.Init());
|
||||||
|
EXPECT_EQ(MpdBuilder::kStatic,
|
||||||
|
GetMpdBuilderType(on_demand_notifier));
|
||||||
|
SimpleMpdNotifier live_notifier(kLiveProfile, empty_mpd_option_,
|
||||||
|
empty_base_urls_, output_path_);
|
||||||
|
EXPECT_TRUE(live_notifier.Init());
|
||||||
|
EXPECT_EQ(MpdBuilder::kDynamic, GetMpdBuilderType(live_notifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify NotifyNewContainer() works as expected for VOD.
|
||||||
|
TEST_P(SimpleMpdNotifierTest, NotifyNewContainer) {
|
||||||
|
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
||||||
|
empty_base_urls_, output_path_);
|
||||||
|
|
||||||
|
const uint32_t kRepresentationId = 1u;
|
||||||
|
const MpdBuilder::MpdType mpd_type = GetParam();
|
||||||
|
scoped_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder(mpd_type));
|
||||||
|
scoped_ptr<MockRepresentation> mock_representation(
|
||||||
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
||||||
|
.WillOnce(Return(mock_representation.get()));
|
||||||
|
|
||||||
|
if (mpd_type == MpdBuilder::kStatic)
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, ToString(_)).WillOnce(Return(true));
|
||||||
|
|
||||||
|
uint32_t unused_container_id;
|
||||||
|
SetMpdBuilder(¬ifier, mock_mpd_builder.PassAs<MpdBuilder>());
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
|
&unused_container_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify NotifySampleDuration() works as expected for Live.
|
||||||
|
TEST_F(SimpleMpdNotifierTest, LiveNotifySampleDuration) {
|
||||||
|
SimpleMpdNotifier notifier(kLiveProfile, empty_mpd_option_, empty_base_urls_,
|
||||||
|
output_path_);
|
||||||
|
|
||||||
|
const uint32_t kRepresentationId = 8u;
|
||||||
|
scoped_ptr<MockMpdBuilder> mock_mpd_builder(DynamicMpdBuilderMock());
|
||||||
|
scoped_ptr<MockRepresentation> mock_representation(
|
||||||
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
||||||
|
.WillOnce(Return(mock_representation.get()));
|
||||||
|
|
||||||
|
uint32_t container_id;
|
||||||
|
SetMpdBuilder(¬ifier, mock_mpd_builder.PassAs<MpdBuilder>());
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
|
&container_id));
|
||||||
|
EXPECT_EQ(kRepresentationId, container_id);
|
||||||
|
|
||||||
|
const uint32_t kSampleDuration = 100;
|
||||||
|
EXPECT_CALL(*mock_representation, SetSampleDuration(kSampleDuration));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
notifier.NotifySampleDuration(kRepresentationId, kSampleDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that NotifySampleDuration works for OnDemand profile.
|
||||||
|
// TODO(rkuroiwa): SimpleMpdNotifier returns a container ID but does not
|
||||||
|
// register it to its map for VOD. Must fix and enable this test.
|
||||||
|
// This test can be also parmeterized just like NotifyNewContainer() test, once
|
||||||
|
// it is fixed.
|
||||||
|
TEST_F(SimpleMpdNotifierTest, DISABLED_OnDemandNotifySampleDuration) {
|
||||||
|
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
||||||
|
empty_base_urls_, output_path_);
|
||||||
|
|
||||||
|
const uint32_t kRepresentationId = 14u;
|
||||||
|
scoped_ptr<MockMpdBuilder> mock_mpd_builder(StaticMpdBuilderMock());
|
||||||
|
scoped_ptr<MockRepresentation> mock_representation(
|
||||||
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
||||||
|
.WillOnce(Return(mock_representation.get()));
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, ToString(_)).WillOnce(Return(true));
|
||||||
|
|
||||||
|
uint32_t container_id;
|
||||||
|
SetMpdBuilder(¬ifier, mock_mpd_builder.PassAs<MpdBuilder>());
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
|
&container_id));
|
||||||
|
EXPECT_EQ(kRepresentationId, container_id);
|
||||||
|
|
||||||
|
const uint32_t kSampleDuration = 100;
|
||||||
|
EXPECT_CALL(*mock_representation, SetSampleDuration(kSampleDuration));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
notifier.NotifySampleDuration(kRepresentationId, kSampleDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that NotifyNewSegment() for live works.
|
||||||
|
TEST_F(SimpleMpdNotifierTest, LiveNotifyNewSegment) {
|
||||||
|
SimpleMpdNotifier notifier(kLiveProfile, empty_mpd_option_, empty_base_urls_,
|
||||||
|
output_path_);
|
||||||
|
|
||||||
|
const uint32_t kRepresentationId = 447834u;
|
||||||
|
scoped_ptr<MockMpdBuilder> mock_mpd_builder(DynamicMpdBuilderMock());
|
||||||
|
scoped_ptr<MockRepresentation> mock_representation(
|
||||||
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
||||||
|
.WillOnce(Return(mock_representation.get()));
|
||||||
|
|
||||||
|
// Expect call at NotifyNewSegment(). But putting expect call here because the
|
||||||
|
// next line passes the value to the notifier.
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, ToString(_)).WillOnce(Return(true));
|
||||||
|
|
||||||
|
uint32_t container_id;
|
||||||
|
SetMpdBuilder(¬ifier, mock_mpd_builder.PassAs<MpdBuilder>());
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
|
&container_id));
|
||||||
|
EXPECT_EQ(kRepresentationId, container_id);
|
||||||
|
|
||||||
|
const uint64_t kStartTime = 0u;
|
||||||
|
const uint32_t kSegmentDuration = 100u;
|
||||||
|
const uint64_t kSegmentSize = 123456u;
|
||||||
|
EXPECT_CALL(*mock_representation,
|
||||||
|
AddNewSegment(kStartTime, kSegmentDuration, kSegmentSize));
|
||||||
|
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewSegment(kRepresentationId, kStartTime,
|
||||||
|
kSegmentDuration, kSegmentSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify AddContentProtectionElement() works. Profile doesn't matter.
|
||||||
|
// TODO(rkuroiwa): Not implemented yet, enable once it is implemented.
|
||||||
|
TEST_F(SimpleMpdNotifierTest, DISABLED_AddContentProtectionElement) {
|
||||||
|
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
||||||
|
empty_base_urls_, output_path_);
|
||||||
|
|
||||||
|
const uint32_t kRepresentationId = 0u;
|
||||||
|
scoped_ptr<MockMpdBuilder> mock_mpd_builder(StaticMpdBuilderMock());
|
||||||
|
scoped_ptr<MockRepresentation> mock_representation(
|
||||||
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
||||||
|
.WillOnce(Return(mock_representation.get()));
|
||||||
|
EXPECT_CALL(*mock_mpd_builder, ToString(_)).WillOnce(Return(true));
|
||||||
|
|
||||||
|
uint32_t container_id;
|
||||||
|
SetMpdBuilder(¬ifier, mock_mpd_builder.PassAs<MpdBuilder>());
|
||||||
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
|
&container_id));
|
||||||
|
EXPECT_EQ(kRepresentationId, container_id);
|
||||||
|
|
||||||
|
ContentProtectionElement element;
|
||||||
|
EXPECT_CALL(*mock_representation, AddContentProtectionElement(_));
|
||||||
|
EXPECT_TRUE(notifier.AddContentProtectionElement(kRepresentationId, element));
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(StaticAndDynamic,
|
||||||
|
SimpleMpdNotifierTest,
|
||||||
|
::testing::Values(MpdBuilder::kStatic,
|
||||||
|
MpdBuilder::kDynamic));
|
||||||
|
|
||||||
|
} // namespace edash_packager
|
|
@ -68,7 +68,10 @@
|
||||||
'type': '<(gtest_target_type)',
|
'type': '<(gtest_target_type)',
|
||||||
'sources': [
|
'sources': [
|
||||||
'base/bandwidth_estimator_unittest.cc',
|
'base/bandwidth_estimator_unittest.cc',
|
||||||
|
'base/mock_mpd_builder.h',
|
||||||
|
'base/mock_mpd_builder.cc',
|
||||||
'base/mpd_builder_unittest.cc',
|
'base/mpd_builder_unittest.cc',
|
||||||
|
'base/simple_mpd_notifier_unittest.cc',
|
||||||
'base/xml/xml_node_unittest.cc',
|
'base/xml/xml_node_unittest.cc',
|
||||||
'test/mpd_builder_test_helper.cc',
|
'test/mpd_builder_test_helper.cc',
|
||||||
'test/mpd_builder_test_helper.h',
|
'test/mpd_builder_test_helper.h',
|
||||||
|
|
Loading…
Reference in New Issue