import io import boto3 import pytest from moto import mock_aws from streamstack.core.s3 import S3SeekableFile, open_s3_buffered BUCKET = "test-bucket" KEY = "test/video.mp4" CONTENT = b"Hello World! This is seekable S3 content for testing purposes." @pytest.fixture def s3_object(): with mock_aws(): s3 = boto3.client("s3", region_name="us-east-1") s3.create_bucket(Bucket=BUCKET) s3.put_object(Bucket=BUCKET, Key=KEY, Body=CONTENT) yield s3 def test_readable_and_seekable(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) assert f.readable() is True assert f.seekable() is True def test_size(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) assert f.size == len(CONTENT) def test_initial_position(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) assert f.tell() == 0 def test_read_from_start(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) data = f.read(5) assert data == CONTENT[:5] assert f.tell() == 5 def test_seek_set(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) pos = f.seek(7) assert pos == 7 assert f.tell() == 7 data = f.read(5) assert data == CONTENT[7:12] def test_seek_cur(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) f.read(5) f.seek(2, io.SEEK_CUR) assert f.tell() == 7 def test_seek_end(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) pos = f.seek(-5, io.SEEK_END) assert pos == len(CONTENT) - 5 data = f.read() assert data == CONTENT[-5:] def test_seek_beyond_end_clamps(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) pos = f.seek(len(CONTENT) + 100) assert pos == len(CONTENT) def test_read_at_eof_returns_empty(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) f.seek(0, io.SEEK_END) buf = bytearray(10) n = f.readinto(buf) assert n == 0 def test_full_read(s3_object): f = S3SeekableFile(BUCKET, KEY, s3_client=s3_object) data = f.read() assert data == CONTENT def test_open_s3_buffered(s3_object): with mock_aws(): s3 = boto3.client("s3", region_name="us-east-1") s3.create_bucket(Bucket=BUCKET) s3.put_object(Bucket=BUCKET, Key=KEY, Body=CONTENT) with patch_s3_client(s3): buf = open_s3_buffered(BUCKET, KEY) assert isinstance(buf, io.BufferedReader) data = buf.read(5) assert data == CONTENT[:5] def patch_s3_client(client): from unittest.mock import patch return patch("streamstack.core.s3.get_s3_client", return_value=client)