Beispiel #1
0
def test_original_video():
    """ Tests that the original_video property returns the VideoFile with 'original' encoding """
    video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a")
    videofiles = [
        VideoFileFactory(video=video,
                         s3_object_key="original.mp4",
                         encoding=EncodingNames.ORIGINAL),
        VideoFileFactory(video=video,
                         s3_object_key="transcoded.hls",
                         encoding=EncodingNames.HLS),
    ]
    assert video.original_video == videofiles[0]
Beispiel #2
0
def test_transcoded_hls_video():
    """ Tests that Video.transcoded_videos returns transcoded HLS videofile"""
    video = VideoFactory()
    videofiles = [
        VideoFileFactory(video=video,
                         s3_object_key="original.mp4",
                         encoding=EncodingNames.ORIGINAL),
        VideoFileFactory(video=video,
                         s3_object_key="video.m3u8",
                         encoding=EncodingNames.HLS),
    ]
    assert len(video.transcoded_videos) == 1
    assert video.transcoded_videos[0] == videofiles[1]
Beispiel #3
0
def test_upload_video(mocker):
    """
    Test that the upload_video task calls the YouTube API execute method
    """
    videofile = VideoFileFactory()
    youtube_id = "M6LymW_8qVk"
    video_upload_response = {
        "id": youtube_id,
        "kind": "youtube#video",
        "snippet": {
            "description": "Testing description",
            "title": "Testing123"
        },
        "status": {
            "uploadStatus": "uploaded"
        },
    }
    youtube_mocker = mocker.patch("cloudsync.youtube.build")
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.side_effect = [
        (None, None),
        (None, video_upload_response),
    ]
    response = YouTubeApi().upload_video(videofile.video)
    assert response == video_upload_response
Beispiel #4
0
def test_video_sources_mp4():
    """ Tests that the video sources property returns the expected sorted results for MP4 """
    video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a")
    videofiles = [
        VideoFileFactory(video=video,
                         s3_object_key="medium.mp4",
                         encoding=EncodingNames.MEDIUM),
        VideoFileFactory(video=video,
                         s3_object_key="small.mp4",
                         encoding=EncodingNames.SMALL),
        VideoFileFactory(video=video,
                         s3_object_key="large.mp4",
                         encoding=EncodingNames.LARGE),
        VideoFileFactory(video=video,
                         s3_object_key="basic.mp4",
                         encoding=EncodingNames.BASIC),
        VideoFileFactory(video=video,
                         s3_object_key="hd.mp4",
                         encoding=EncodingNames.HD),
    ]
    assert video.sources == [
        {
            "src": videofiles[4].cloudfront_url,
            "label": EncodingNames.HD,
            "type": "video/mp4",
        },
        {
            "src": videofiles[2].cloudfront_url,
            "label": EncodingNames.LARGE,
            "type": "video/mp4",
        },
        {
            "src": videofiles[0].cloudfront_url,
            "label": EncodingNames.MEDIUM,
            "type": "video/mp4",
        },
        {
            "src": videofiles[3].cloudfront_url,
            "label": EncodingNames.BASIC,
            "type": "video/mp4",
        },
        {
            "src": videofiles[1].cloudfront_url,
            "label": EncodingNames.SMALL,
            "type": "video/mp4",
        },
    ]
Beispiel #5
0
def test_s3_object_uniqueness(videofile):
    """
    Test that a videoFile with duplicate s3_object_key value should raise an IntegrityError on save
    """
    with pytest.raises(IntegrityError):
        VideoFileFactory(
            video=videofile.video,
            s3_object_key=videofile.s3_object_key,
        )
Beispiel #6
0
def test_video_sources_hls():
    """ Tests that the video sources property returns the expected result for HLS """
    video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a")
    videofile = VideoFileFactory(video=video, encoding=EncodingNames.HLS)
    assert video.sources == [{
        "src": videofile.cloudfront_url,
        "label": EncodingNames.HLS,
        "type": "application/x-mpegURL",
    }]
Beispiel #7
0
def test_download_mp4(encodings, download):
    """ Tests that video.download returns the most appropriate file for download """
    video = VideoFactory()
    for encoding in encodings:
        VideoFileFactory(video=video,
                         s3_object_key="{}.mp4".format(encoding),
                         encoding=encoding)
    if not download:
        assert video.download is None
    else:
        assert video.download.encoding == download
Beispiel #8
0
def test_transcoded_mp4_video():
    """ Tests that Video.transcoded_videos returns transcoded MP4 videos in the correct order"""
    video = VideoFactory()
    videofiles = [
        VideoFileFactory(video=video,
                         s3_object_key="original.mp4",
                         encoding=EncodingNames.ORIGINAL),
        VideoFileFactory(video=video,
                         s3_object_key="small.mp4",
                         encoding=EncodingNames.SMALL),
        VideoFileFactory(video=video,
                         s3_object_key="basic.mp4",
                         encoding=EncodingNames.BASIC),
        VideoFileFactory(video=video,
                         s3_object_key="HD.mp4",
                         encoding=EncodingNames.HD),
    ]
    assert len(video.transcoded_videos) == 3
    assert video.transcoded_videos[0] == videofiles[3]
    assert video.transcoded_videos[1] == videofiles[2]
    assert video.transcoded_videos[2] == videofiles[1]
Beispiel #9
0
def test_upload_errors_retryable(mocker, error, retryable):
    """
    Test that uploads are retried 10x for retryable exceptions
    """
    youtube_mocker = mocker.patch("cloudsync.youtube.build")
    mocker.patch("cloudsync.youtube.time")
    videofile = VideoFileFactory()
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.side_effect = (error)
    with pytest.raises(Exception) as exc:
        YouTubeApi().upload_video(videofile.video)
    assert str(exc.value).startswith("Retried YouTube upload 10x") == retryable
Beispiel #10
0
def test_upload_video_no_id(mocker):
    """
    Test that the upload_video task fails if the response contains no id
    """
    videofile = VideoFileFactory()
    youtube_mocker = mocker.patch("cloudsync.youtube.build")
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.return_value = (
        None,
        {},
    )
    with pytest.raises(YouTubeUploadException):
        YouTubeApi().upload_video(videofile.video)
Beispiel #11
0
def test_upload_video_long_fields(mocker):
    """
    Test that the upload_youtube_video task truncates title and description if too long
    """
    title = "".join(random.choice(string.ascii_lowercase) for c in range(105))
    desc = "".join(random.choice(string.ascii_lowercase) for c in range(5005))
    video = VideoFactory.create(title=title,
                                description=desc,
                                is_public=True,
                                status=VideoStatus.COMPLETE)
    VideoFileFactory(video=video)
    mocker.patch("cloudsync.youtube.resumable_upload")
    youtube_mocker = mocker.patch("cloudsync.youtube.build")
    mock_upload = youtube_mocker().videos.return_value.insert
    YouTubeApi().upload_video(video)
    called_args, called_kwargs = mock_upload.call_args
    assert called_kwargs["body"]["snippet"]["title"] == title[:100]
    assert called_kwargs["body"]["snippet"]["description"] == desc[:5000]
Beispiel #12
0
def test_video_sources_youtube(youtube_status, is_public, stream_source):
    """ Tests that a public video can play from cloudfront if a youtube video does not exist """
    public_video = VideoFactory.create(
        key="8494dafc-3665-4960-8e00-9790574ec93a",
        is_public=is_public,
        collection=CollectionFactory(stream_source=stream_source),
    )
    videofiles = [
        VideoFileFactory(video=public_video,
                         s3_object_key="hd.mp4",
                         encoding=EncodingNames.HD),
    ]
    if youtube_status is not None:
        YouTubeVideoFactory.create(video=public_video, status=youtube_status)
    if (youtube_status == YouTubeStatus.PROCESSED and is_public
            and stream_source == StreamSource.YOUTUBE):
        assert public_video.sources == []
    else:
        assert public_video.sources == [{
            "src": videofiles[0].cloudfront_url,
            "label": EncodingNames.HD,
            "type": "video/mp4",
        }]
Beispiel #13
0
def videofile():
    """Fixture to create a video file"""
    return VideoFileFactory()
def video_with_file():
    """ Fixture to create a video with an original videofile """
    video_file = VideoFileFactory(
        video__is_public=True, encoding=EncodingNames.ORIGINAL
    )
    return video_file.video
Beispiel #15
0
def test_sort_transcoded_m3u8_files(mocker):
    # pylint: disable=too-many-locals
    """
    Test that sort_transcoded_m3u8_files changes the m3u8 file on s3 if it needs to be sorted
    """
    s3 = boto3.resource("s3")
    s3c = boto3.client("s3")

    bucket_name = "MYBUCKET"
    s3c.create_bucket(Bucket=bucket_name)
    bucket = s3.Bucket(bucket_name)
    mocker.patch("cloudsync.tasks.settings.VIDEO_S3_TRANSCODE_BUCKET",
                 bucket_name)

    file_key = "key"
    file_body = """
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981867-06dkm6.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4881000,RESOLUTION=1920x1080,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981921-c2jlwt.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1920x1080,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981921-c2jlwt.m3u8
"""
    s3c.put_object(Body=file_body, Bucket=bucket_name, Key=file_key)
    VideoFileFactory(s3_object_key=file_key, encoding="HLS")

    already_sorted_file_key = "already_sorted"
    already_sorted_file_body = """
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4881000,RESOLUTION=1920x1080,CODECS="avc1.4d001f,mp4a.40.2"
video_1604127981921-c2jlwt.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
video_1604127981867-06dkm6.m3u8
"""
    s3c.put_object(Body=already_sorted_file_body,
                   Bucket=bucket_name,
                   Key=already_sorted_file_key)
    VideoFileFactory(s3_object_key=already_sorted_file_key, encoding="HLS")

    invalid_header_file_key = "invalid_header"
    invalid_header_file_body = """
invalid_header
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981867-06dkm6.m3u8
"""
    s3c.put_object(Body=invalid_header_file_body,
                   Bucket=bucket_name,
                   Key=invalid_header_file_key)
    VideoFileFactory(s3_object_key=invalid_header_file_key, encoding="HLS")

    invalid_content_file_key = "invalid_content"
    invalid_content_file_body = """
#EXTM3U
#EXT-X-STREAM-INF: No
#EXT-X-STREAM-INF: RESOLUTIONS
"""
    s3c.put_object(Body=invalid_content_file_body,
                   Bucket=bucket_name,
                   Key=invalid_content_file_key)
    VideoFileFactory(s3_object_key=invalid_content_file_key, encoding="HLS")

    # The task should not raise an error if a VideoFile hase a s3_object_key without a corresponding
    # file on s3
    VideoFileFactory(s3_object_key="not a valid key", encoding="HLS")

    sort_transcoded_m3u8_files()

    expected_file_body = """
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4881000,RESOLUTION=1920x1080,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981921-c2jlwt.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1920x1080,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981921-c2jlwt.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2723000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
video_1504127981867-06dkm6.m3u8
"""
    updated_file = s3c.get_object(Bucket=bucket_name, Key=file_key)
    assert updated_file["Body"].read().decode() == expected_file_body

    already_sorted_file = s3c.get_object(Bucket=bucket_name,
                                         Key=already_sorted_file_key)
    assert already_sorted_file["Body"].read().decode(
    ) == already_sorted_file_body

    invalid_header_file = s3c.get_object(Bucket=bucket_name,
                                         Key=invalid_header_file_key)
    assert invalid_header_file["Body"].read().decode(
    ) == invalid_header_file_body

    invalid_content_file = s3c.get_object(Bucket=bucket_name,
                                          Key=invalid_content_file_key)
    assert invalid_content_file["Body"].read().decode(
    ) == invalid_content_file_body