Cleanup packager_test.py

- Support decryption verification in _CheckTestResults
- Allow diff_files in _CheckTestResults
- Update all functional tests to use _CheckTestResults

Change-Id: I3f9c02f35808eba787becf9b1e5c1ce9238f943e
This commit is contained in:
KongQun Yang 2018-07-11 11:57:21 -07:00
parent 5dd21179ec
commit b4ae6561f8
60 changed files with 208 additions and 186 deletions

View File

@ -83,7 +83,8 @@ base::Optional<StreamDescriptor> ParseStreamDescriptor(
base::StringPairs pairs; base::StringPairs pairs;
if (!base::SplitStringIntoKeyValuePairs(descriptor_string, '=', ',', if (!base::SplitStringIntoKeyValuePairs(descriptor_string, '=', ',',
&pairs)) { &pairs)) {
LOG(ERROR) << "Invalid stream descriptors name/value pairs."; LOG(ERROR) << "Invalid stream descriptors name/value pairs: "
<< descriptor_string;
return base::nullopt; return base::nullopt;
} }
for (base::StringPairs::const_iterator iter = pairs.begin(); for (base::StringPairs::const_iterator iter = pairs.begin();

View File

@ -42,6 +42,20 @@ class StreamDescriptor(object):
return self.buffer return self.buffer
class DiffFilesPolicy(object):
"""Specifies the policy for diff_files.
Attributes:
allowed_diff_files: The list of files allowed to be different.
exact: The actual list of diff_files must match the above list exactly, i.e.
all the files in the above list must be different.
"""
def __init__(self, allowed_diff_files, exact):
self.allowed_diff_files = allowed_diff_files
self.exact = exact
def _UpdateMediaInfoPaths(media_info_filepath): def _UpdateMediaInfoPaths(media_info_filepath):
# Example: # Example:
# before: media_file_name: "/tmp/tmpD1h5UC/bear-640x360-audio.mp4" # before: media_file_name: "/tmp/tmpD1h5UC/bear-640x360-audio.mp4"
@ -144,6 +158,7 @@ class PackagerAppTest(unittest.TestCase):
def _GetStream(self, def _GetStream(self,
descriptor, descriptor,
language=None, language=None,
output_file_prefix=None,
output_format=None, output_format=None,
segmented=False, segmented=False,
hls=False, hls=False,
@ -164,6 +179,8 @@ class PackagerAppTest(unittest.TestCase):
descriptor: The name of the stream in the container that should be used as descriptor: The name of the stream in the container that should be used as
input for the output. input for the output.
language: The language override for the input stream. language: The language override for the input stream.
output_file_prefix: The output file prefix. Default to empty if not
specified.
output_format: Specify the format for the output. output_format: Specify the format for the output.
segmented: Should the output use a segmented formatted. This will affect segmented: Should the output use a segmented formatted. This will affect
the output extensions and manifests. the output extensions and manifests.
@ -197,11 +214,14 @@ class PackagerAppTest(unittest.TestCase):
if language: if language:
stream.Append('lang', language) stream.Append('lang', language)
output_file_name = ''
if output_file_prefix:
output_file_name += '%s-' % output_file_prefix
# Use the input file name (no extension) and pair it with the # Use the input file name (no extension) and pair it with the
# descriptor to create the root of the output file_name. # descriptor to create the root of the output file_name.
output_file_name = '%s-%s' % ( output_file_name += '%s-%s' % (os.path.splitext(
os.path.splitext(input_file_name)[0], os.path.basename(input_file_name))[0], descriptor)
descriptor)
if trick_play_factor: if trick_play_factor:
stream.Append('trick_play_factor', trick_play_factor) stream.Append('trick_play_factor', trick_play_factor)
@ -387,10 +407,6 @@ class PackagerAppTest(unittest.TestCase):
flags += ['--test_packager_version', '<tag>-<hash>-<test>'] flags += ['--test_packager_version', '<tag>-<hash>-<test>']
return flags return flags
def _CompareWithGold(self, test_output, golden_file_name):
golden_file = os.path.join(self.golden_file_dir, golden_file_name)
return filecmp.cmp(test_output, golden_file)
def _GitDiff(self, file_a, file_b): def _GitDiff(self, file_a, file_b):
cmd = [ cmd = [
'git', 'git',
@ -405,45 +421,41 @@ class PackagerAppTest(unittest.TestCase):
p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
return p.communicate() return p.communicate()
def _DiffGold(self, test_output, golden_file_name): def _AssertStreamInfo(self, stream, info):
golden_file = os.path.join(self.golden_file_dir, golden_file_name) stream_info = self.packager.DumpStreamInfo(stream)
if test_env.options.test_update_golden_files: self.assertIn('Found 1 stream(s).', stream_info)
if not os.path.exists(golden_file) or not filecmp.cmp(test_output, self.assertIn(info, stream_info)
golden_file):
print 'Updating golden file: ', golden_file_name
shutil.copyfile(test_output, golden_file)
else:
match = filecmp.cmp(test_output, golden_file)
if not match:
output, error = self._GitDiff(golden_file, test_output)
command_line = self.packager.GetCommandLine()
failure_message = '\n'.join([
output,
error,
_TEST_FAILURE_COMMAND_LINE_MESSAGE,
command_line
])
self.fail(failure_message)
# TODO(vaage): Replace all used of this with |_CheckTestResults|. def _Decrypt(self, file_path, output_format):
def _DiffLiveGold(self, streams = [
test_output_prefix, self._GetStream(
golden_file_name_prefix, '0',
output_format='mp4'): output_file_prefix='decrypted',
# Compare init and the first three segments. output_format=output_format,
if output_format == 'ts': test_file=file_path)
for i in range(1, 4): ]
self._DiffGold('%s-%d.ts' % (test_output_prefix, i), self.assertPackageSuccess(streams, self._GetFlags(decryption=True))
'%s-%d.ts' % (golden_file_name_prefix, i))
else:
self._DiffGold(test_output_prefix + '-init.mp4',
golden_file_name_prefix + '-init.mp4')
for i in range(1, 4):
self._DiffGold('%s-%d.m4s' % (test_output_prefix, i),
'%s-%d.m4s' % (golden_file_name_prefix, i))
# |test_dir| is expected to be relative to |self.golden_file_dir|. def _CheckTestResults(self,
def _CheckTestResults(self, test_dir): test_dir,
verify_decryption=False,
diff_files_policy=None,
allow_updating_golden_files=True):
"""Check test results. Updates golden files in update mode.
Args:
test_dir: The golden directory to be compared with. It is expected to be
relative to |self.golden_file_dir|.
verify_decryption: If set to true, assumes the media files without
'skip-encryption' in name to be encrypted and tries to decrypt and
then compare these files.
diff_files_policy: Some files are allowed to be different if this argument
is specified.
allow_updating_golden_files: When set to false, golden files will not be
updated for this test even if updating_golden_files is requested by
user. This is useful for tests generating different outputs in each
run, which is often used together with a non-default DiffFilesPolicy.
"""
# Live mpd contains current availabilityStartTime and publishTime, which # Live mpd contains current availabilityStartTime and publishTime, which
# needs to be replaced before comparison. If this is not a live test, then # needs to be replaced before comparison. If this is not a live test, then
# this will be a no-op. # this will be a no-op.
@ -457,10 +469,19 @@ class PackagerAppTest(unittest.TestCase):
for media_info in media_infos: for media_info in media_infos:
_UpdateMediaInfoPaths(media_info) _UpdateMediaInfoPaths(media_info)
if verify_decryption:
for file_name in os.listdir(self.tmp_dir):
if 'skip_encryption' in file_name:
continue
extension = os.path.splitext(file_name)[1][1:]
if extension not in ['mpd', 'm3u8', 'media_info']:
self._Decrypt(os.path.join(self.tmp_dir, file_name), extension)
if test_env.options.test_update_golden_files: if test_env.options.test_update_golden_files:
if allow_updating_golden_files:
self._UpdateGold(test_dir) self._UpdateGold(test_dir)
else: else:
self._DiffDir(test_dir) self._DiffDir(test_dir, diff_files_policy)
# |test_dir| is expected to be relative to |self.golden_file_dir|. # |test_dir| is expected to be relative to |self.golden_file_dir|.
def _UpdateGold(self, test_dir): def _UpdateGold(self, test_dir):
@ -472,8 +493,15 @@ class PackagerAppTest(unittest.TestCase):
shutil.copytree(out_dir, gold_dir) shutil.copytree(out_dir, gold_dir)
# |test_dir| is expected to be relative to |self.golden_file_dir|. def _DiffDir(self, test_dir, diff_files_policy=None):
def _DiffDir(self, test_dir): """Compare test output to golden output.
Args:
test_dir: The golden directory to be compared with. It is expected to be
relative to |self.golden_file_dir|.
diff_files_policy: Some files are allowed to be different if this argument
is specified.
"""
out_dir = self.tmp_dir out_dir = self.tmp_dir
gold_dir = os.path.join(self.golden_file_dir, test_dir) gold_dir = os.path.join(self.golden_file_dir, test_dir)
@ -499,6 +527,10 @@ class PackagerAppTest(unittest.TestCase):
# Produce nice diffs for each file that differs. # Produce nice diffs for each file that differs.
for diff_file in diff.diff_files: for diff_file in diff.diff_files:
if diff_files_policy:
if diff_file in diff_files_policy.allowed_diff_files:
continue
actual_file = os.path.join(out_dir, diff_file) actual_file = os.path.join(out_dir, diff_file)
expected_file = os.path.join(gold_dir, diff_file) expected_file = os.path.join(gold_dir, diff_file)
@ -510,6 +542,11 @@ class PackagerAppTest(unittest.TestCase):
if error: if error:
failure_messages += [error] failure_messages += [error]
if diff_files_policy and diff_files_policy.exact:
for diff_file in diff_files_policy.allowed_diff_files:
if diff_file not in diff.diff_files:
failure_messages += ['Expecting "%s" to be different' % diff_file]
if failure_messages: if failure_messages:
# Prepend the failure messages with the header. # Prepend the failure messages with the header.
failure_messages = [ failure_messages = [
@ -851,9 +888,7 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('encryption') self._CheckTestResults('encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
# Test deprecated flag --enable_fixed_key_encryption, which is still # Test deprecated flag --enable_fixed_key_encryption, which is still
# supported currently. # supported currently.
@ -865,9 +900,7 @@ class PackagerFunctionalTest(PackagerAppTest):
self.encryption_iv) self.encryption_iv)
] ]
self.assertPackageSuccess(self._GetStreams(['audio', 'video']), flags) self.assertPackageSuccess(self._GetStreams(['audio', 'video']), flags)
self._CheckTestResults('encryption-using-fixed-key') self._CheckTestResults('encryption-using-fixed-key', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionMultiKeys(self): def testEncryptionMultiKeys(self):
audio_key_id = '10111213141516171819202122232425' audio_key_id = '10111213141516171819202122232425'
@ -884,13 +917,6 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(self._GetStreams(['audio', 'video']), flags) self.assertPackageSuccess(self._GetStreams(['audio', 'video']), flags)
self._CheckTestResults('encryption-multi-keys') self._CheckTestResults('encryption-multi-keys')
self.encryption_key_id = audio_key_id
self.encryption_key = audio_key
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self.encryption_key_id = video_key_id
self.encryption_key = video_key
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionMultiKeysWithStreamLabel(self): def testEncryptionMultiKeysWithStreamLabel(self):
audio_key_id = '20212223242526272829303132333435' audio_key_id = '20212223242526272829303132333435'
audio_key = '21222324252627282930313233343536' audio_key = '21222324252627282930313233343536'
@ -913,13 +939,6 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('encryption-multi-keys-with-stream-label') self._CheckTestResults('encryption-multi-keys-with-stream-label')
self.encryption_key_id = audio_key_id
self.encryption_key = audio_key
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self.encryption_key_id = video_key_id
self.encryption_key = video_key
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionOfOnlyVideoStream(self): def testEncryptionOfOnlyVideoStream(self):
streams = [ streams = [
self._GetStream('audio', skip_encryption=True), self._GetStream('audio', skip_encryption=True),
@ -928,8 +947,8 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True) flags = self._GetFlags(encryption=True, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('encryption-of-only-video-stream') self._CheckTestResults(
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') 'encryption-of-only-video-stream', verify_decryption=True)
def testEncryptionAndTrickPlay(self): def testEncryptionAndTrickPlay(self):
streams = [ streams = [
@ -940,10 +959,7 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(streams, self.assertPackageSuccess(streams,
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('encryption-and-trick-play') self._CheckTestResults('encryption-and-trick-play', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
self._VerifyDecryption(self.output[2], 'bear-640x360-v-trick-1-golden.mp4')
# TODO(hmchen): Add a test case that SD and HD AdapatationSet share one trick # TODO(hmchen): Add a test case that SD and HD AdapatationSet share one trick
# play stream. # play stream.
@ -958,10 +974,6 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(streams, self.assertPackageSuccess(streams,
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('encryption-and-two-trick-plays') self._CheckTestResults('encryption-and-two-trick-plays')
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
self._VerifyDecryption(self.output[2], 'bear-640x360-v-trick-1-golden.mp4')
self._VerifyDecryption(self.output[3], 'bear-640x360-v-trick-2-golden.mp4')
def testEncryptionAndNoClearLead(self): def testEncryptionAndNoClearLead(self):
streams = [ streams = [
@ -972,9 +984,8 @@ class PackagerFunctionalTest(PackagerAppTest):
self.clear_lead = 0 self.clear_lead = 0
self.assertPackageSuccess(streams, self.assertPackageSuccess(streams,
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('encryption-and-no-clear-lead') self._CheckTestResults(
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4') 'encryption-and-no-clear-lead', verify_decryption=True)
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionAndNoPsshInStream(self): def testEncryptionAndNoPsshInStream(self):
self.assertPackageSuccess( self.assertPackageSuccess(
@ -982,45 +993,33 @@ class PackagerFunctionalTest(PackagerAppTest):
self._GetFlags( self._GetFlags(
encryption=True, include_pssh_in_stream=False, output_dash=True)) encryption=True, include_pssh_in_stream=False, output_dash=True))
self._CheckTestResults('encryption-and-no-pssh-in-stream') self._CheckTestResults('encryption-and-no-pssh-in-stream')
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionCbc1(self): def testEncryptionCbc1(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags( self._GetFlags(
encryption=True, protection_scheme='cbc1', output_dash=True)) encryption=True, protection_scheme='cbc1', output_dash=True))
self._CheckTestResults('encryption-cbc-1') self._CheckTestResults('encryption-cbc-1', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionCens(self): def testEncryptionCens(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags( self._GetFlags(
encryption=True, protection_scheme='cens', output_dash=True)) encryption=True, protection_scheme='cens', output_dash=True))
self._CheckTestResults('encryption-cens') self._CheckTestResults('encryption-cens', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionCbcs(self): def testEncryptionCbcs(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags( self._GetFlags(
encryption=True, protection_scheme='cbcs', output_dash=True)) encryption=True, protection_scheme='cbcs', output_dash=True))
self._DiffGold(self.output[0], 'bear-640x360-a-cbcs-golden.mp4') self._CheckTestResults('encryption-cbcs', verify_decryption=True)
self._DiffGold(self.output[1], 'bear-640x360-v-cbcs-golden.mp4')
self._DiffGold(self.mpd_output, 'bear-640x360-av-cbcs-golden.mpd')
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionAndAdCues(self): def testEncryptionAndAdCues(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags(encryption=True, output_dash=True, ad_cues='1.5')) self._GetFlags(encryption=True, output_dash=True, ad_cues='1.5'))
self._CheckTestResults('encryption-and-ad-cues') self._CheckTestResults('encryption-and-ad-cues')
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4')
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4')
def testEncryptionAndAdCuesSplitContent(self): def testEncryptionAndAdCuesSplitContent(self):
self.assertPackageSuccess( self.assertPackageSuccess(
@ -1073,9 +1072,7 @@ class PackagerFunctionalTest(PackagerAppTest):
] ]
self.assertPackageSuccess(streams, self.assertPackageSuccess(streams,
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('webm-subsample-encryption') self._CheckTestResults('webm-subsample-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0],
'bear-320x180-vp9-altref-dec-golden.webm')
def testWebmVp9FullSampleEncryption(self): def testWebmVp9FullSampleEncryption(self):
streams = [ streams = [
@ -1087,9 +1084,8 @@ class PackagerFunctionalTest(PackagerAppTest):
encryption=True, vp9_subsample_encryption=False, output_dash=True) encryption=True, vp9_subsample_encryption=False, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('webm-vp9-full-sample-encryption') self._CheckTestResults(
self._VerifyDecryption(self.output[0], 'webm-vp9-full-sample-encryption', verify_decryption=True)
'bear-320x180-vp9-altref-dec-golden.webm')
def testAvcTsWithEncryption(self): def testAvcTsWithEncryption(self):
# Currently we only support live packaging for ts. # Currently we only support live packaging for ts.
@ -1194,8 +1190,7 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True) flags = self._GetFlags(encryption=True, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('webm-with-encryption') self._CheckTestResults('webm-with-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-vp8-golden.webm')
def testHevcWithEncryption(self): def testHevcWithEncryption(self):
streams = [ streams = [
@ -1204,8 +1199,7 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True) flags = self._GetFlags(encryption=True, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('hevc-with-encryption') self._CheckTestResults('hevc-with-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-hevc-golden.mp4')
def testVp8Mp4WithEncryption(self): def testVp8Mp4WithEncryption(self):
streams = [ streams = [
@ -1216,8 +1210,7 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True) flags = self._GetFlags(encryption=True, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('vp8-mp4-with-encryption') self._CheckTestResults('vp8-mp4-with-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-640x360-vp8-golden.mp4')
def testOpusVp9Mp4WithEncryption(self): def testOpusVp9Mp4WithEncryption(self):
streams = [ streams = [
@ -1231,9 +1224,8 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True) flags = self._GetFlags(encryption=True, output_dash=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('opus-vp9-mp4-with-encryption') self._CheckTestResults(
self._VerifyDecryption(self.output[0], 'bear-320x240-opus-golden.mp4') 'opus-vp9-mp4-with-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[1], 'bear-320x240-vp9-golden.mp4')
def testFlacWithEncryption(self): def testFlacWithEncryption(self):
streams = [ streams = [
@ -1243,8 +1235,7 @@ class PackagerFunctionalTest(PackagerAppTest):
flags = self._GetFlags(encryption=True, output_dash=True, output_hls=True) flags = self._GetFlags(encryption=True, output_dash=True, output_hls=True)
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('flac-with-encryption') self._CheckTestResults('flac-with-encryption', verify_decryption=True)
self._VerifyDecryption(self.output[0], 'bear-flac-golden.mp4')
def testWvmInput(self): def testWvmInput(self):
self.encryption_key = '9248d245390e0a49d483ba9b43fc69c3' self.encryption_key = '9248d245390e0a49d483ba9b43fc69c3'
@ -1276,41 +1267,39 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags(encryption=True, random_iv=True, output_dash=True)) self._GetFlags(encryption=True, random_iv=True, output_dash=True))
self._AssertStreamInfo(self.output[0], 'is_encrypted: true')
self._AssertStreamInfo(self.output[1], 'is_encrypted: true')
# The outputs are encrypted with random iv, so they are not the same as # The outputs are encrypted with random iv, so they are not the same as
# golden files. # golden files.
self.assertFalse(self._CompareWithGold(self.output[0], self._CheckTestResults(
'bear-640x360-a-cenc-golden.mp4')) 'encryption',
self.assertFalse(self._CompareWithGold(self.output[1], verify_decryption=True,
'bear-640x360-v-cenc-golden.mp4')) diff_files_policy=DiffFilesPolicy(
self._DiffGold(self.mpd_output, 'bear-640x360-av-cenc-golden.mpd') allowed_diff_files=[
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4') 'bear-640x360-audio.mp4', 'bear-640x360-video.mp4'
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') ],
exact=True),
allow_updating_golden_files=False)
def testEncryptionAndRealClock(self): def testEncryptionAndRealClock(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags(encryption=True, output_dash=True, use_fake_clock=False)) self._GetFlags(encryption=True, output_dash=True, use_fake_clock=False))
self._AssertStreamInfo(self.output[0], 'is_encrypted: true')
self._AssertStreamInfo(self.output[1], 'is_encrypted: true')
# The outputs are generated with real clock, so they are not the same as # The outputs are generated with real clock, so they are not the same as
# golden files. # golden files.
self.assertFalse(self._CompareWithGold(self.output[0], self._CheckTestResults(
'bear-640x360-a-cenc-golden.mp4')) 'encryption',
self.assertFalse(self._CompareWithGold(self.output[1], verify_decryption=True,
'bear-640x360-v-cenc-golden.mp4')) diff_files_policy=DiffFilesPolicy(
self._DiffGold(self.mpd_output, 'bear-640x360-av-cenc-golden.mpd') allowed_diff_files=[
self._VerifyDecryption(self.output[0], 'bear-640x360-a-demuxed-golden.mp4') 'bear-640x360-audio.mp4', 'bear-640x360-video.mp4'
self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') ],
exact=True),
allow_updating_golden_files=False)
def testEncryptionAndNonDashIfIop(self): def testEncryptionAndNonDashIfIop(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video']), self._GetStreams(['audio', 'video']),
self._GetFlags(encryption=True, dash_if_iop=False, output_dash=True)) self._GetFlags(encryption=True, dash_if_iop=False, output_dash=True))
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4') self._CheckTestResults('encryption-and-non-dash-if-iop')
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
self._DiffGold(self.mpd_output, 'bear-640x360-av-cenc-non-iop-golden.mpd')
def testEncryptionAndOutputMediaInfo(self): def testEncryptionAndOutputMediaInfo(self):
self.assertPackageSuccess( self.assertPackageSuccess(
@ -1444,12 +1433,14 @@ class PackagerFunctionalTest(PackagerAppTest):
test_files=['bear-1280x720.mp4', 'bear-640x360.mp4', test_files=['bear-1280x720.mp4', 'bear-640x360.mp4',
'bear-320x180.mp4']), 'bear-320x180.mp4']),
self._GetFlags(encryption=True, output_dash=True)) self._GetFlags(encryption=True, output_dash=True))
self._DiffLiveGold(self.output[2], 'bear-640x360-a-live-cenc-golden')
self._DiffLiveGold(self.output[3], 'bear-640x360-v-live-cenc-golden')
# Mpd cannot be validated right now since we don't generate determinstic # Mpd cannot be validated right now since we don't generate determinstic
# mpd with multiple inputs due to thread racing. # mpd with multiple inputs due to thread racing.
# TODO(b/73349711): Generate determinstic mpd or at least validate mpd # TODO(b/73349711): Generate determinstic mpd or at least validate mpd
# schema. # schema.
self._CheckTestResults(
'live-profile-and-encryption-and-mult-files',
diff_files_policy=DiffFilesPolicy(
allowed_diff_files=['output.mpd'], exact=False))
def testLiveProfileAndKeyRotation(self): def testLiveProfileAndKeyRotation(self):
self.assertPackageSuccess( self.assertPackageSuccess(
@ -1563,20 +1554,6 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('dash-with-bandwidth-override') self._CheckTestResults('dash-with-bandwidth-override')
def _AssertStreamInfo(self, stream, info):
stream_info = self.packager.DumpStreamInfo(stream)
self.assertIn('Found 1 stream(s).', stream_info)
self.assertIn(info, stream_info)
def _VerifyDecryption(self, test_encrypted_file, golden_clear_file):
output_extension = os.path.splitext(golden_clear_file)[1][1:]
self.assertPackageSuccess(
self._GetStreams(['0'],
output_format=output_extension,
test_files=[test_encrypted_file]),
self._GetFlags(decryption=True, output_dash=True))
self._DiffGold(self.output[-1], golden_clear_file)
class PackagerCommandParsingTest(PackagerAppTest): class PackagerCommandParsingTest(PackagerAppTest):

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.802799940109253S">
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</ContentProtection>
<Representation id="0" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-video.mp4</BaseURL>
<SegmentBase indexRange="1091-1158" timescale="30000">
<Initialization range="0-1090"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</ContentProtection>
<Representation id="1" bandwidth="133406" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="967-1034" timescale="44100">
<Initialization range="0-966"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_time" availabilityStartTime="some_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<AdaptationSet id="0" contentType="video" maxWidth="1280" maxHeight="720" frameRate="30000/1001" segmentAlignment="true" par="16:9">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</ContentProtection>
<Representation id="0" bandwidth="383593" codecs="avc1.64000d" mimeType="video/mp4" sar="1:1" width="320" height="180">
<SegmentTemplate timescale="30000" initialization="bear-320x180-video-init.mp4" media="bear-320x180-video-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="32032"/>
<S t="32032" d="30030"/>
<S t="62062" d="23023"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
<Representation id="1" bandwidth="2632184" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" width="1280" height="720">
<SegmentTemplate timescale="30000" initialization="bear-1280x720-video-init.mp4" media="bear-1280x720-video-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="32032"/>
<S t="32032" d="30030"/>
<S t="62062" d="22022"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
<Representation id="3" bandwidth="978382" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
<SegmentTemplate timescale="30000" initialization="bear-640x360-video-init.mp4" media="bear-640x360-video-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="32032"/>
<S t="32032" d="30030"/>
<S t="62062" d="22022"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</ContentProtection>
<Representation id="2" bandwidth="134015" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<SegmentTemplate timescale="44100" initialization="bear-320x180-audio-init.mp4" media="bear-320x180-audio-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="45056"/>
<S t="45056" d="44032"/>
<S t="89088" d="33792"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
<Representation id="4" bandwidth="134015" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<SegmentTemplate timescale="44100" initialization="bear-1280x720-audio-init.mp4" media="bear-1280x720-audio-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="45056"/>
<S t="45056" d="44032"/>
<S t="89088" d="32768"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
<Representation id="5" bandwidth="134015" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<SegmentTemplate timescale="44100" initialization="bear-640x360-audio-init.mp4" media="bear-640x360-audio-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="45056"/>
<S t="45056" d="44032"/>
<S t="89088" d="32768"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>

View File

@ -53,8 +53,8 @@ TEST_F(DemuxerTest, FileNotFound) {
} }
TEST_F(DemuxerTest, EncryptedContentWithoutKeySource) { TEST_F(DemuxerTest, EncryptedContentWithoutKeySource) {
Demuxer demuxer( Demuxer demuxer(GetAppTestDataFilePath("encryption/bear-640x360-video.mp4")
GetAppTestDataFilePath("bear-640x360-v-cenc-golden.mp4").AsUTF8Unsafe()); .AsUTF8Unsafe());
ASSERT_OK(demuxer.SetHandler("video", some_handler())); ASSERT_OK(demuxer.SetHandler("video", some_handler()));
EXPECT_EQ(error::INVALID_ARGUMENT, demuxer.Run().error_code()); EXPECT_EQ(error::INVALID_ARGUMENT, demuxer.Run().error_code());
} }
@ -65,8 +65,8 @@ TEST_F(DemuxerTest, EncryptedContentWithKeySource) {
.WillOnce( .WillOnce(
DoAll(SetArgPointee<1>(GetMockEncryptionKey()), Return(Status::OK))); DoAll(SetArgPointee<1>(GetMockEncryptionKey()), Return(Status::OK)));
Demuxer demuxer( Demuxer demuxer(GetAppTestDataFilePath("encryption/bear-640x360-video.mp4")
GetAppTestDataFilePath("bear-640x360-v-cenc-golden.mp4").AsUTF8Unsafe()); .AsUTF8Unsafe());
demuxer.SetKeySource(std::move(mock_key_source)); demuxer.SetKeySource(std::move(mock_key_source));
ASSERT_OK(demuxer.SetHandler("video", some_handler())); ASSERT_OK(demuxer.SetHandler("video", some_handler()));
EXPECT_OK(demuxer.Run()); EXPECT_OK(demuxer.Run());