|
10 | 10 |
|
11 | 11 | from box_sdk_gen.internal.utils import Iterator |
12 | 12 |
|
| 13 | +from box_sdk_gen.schemas.upload_part_plan_hit import UploadPartPlanHit |
| 14 | + |
13 | 15 | from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer |
14 | 16 |
|
15 | 17 | from box_sdk_gen.internal.utils import hex_to_base_64 |
|
30 | 32 |
|
31 | 33 | from box_sdk_gen.internal.utils import ByteStream |
32 | 34 |
|
| 35 | +from box_sdk_gen.internal.utils import delay_in_seconds |
| 36 | + |
33 | 37 | from test.commons import get_default_client |
34 | 38 |
|
35 | 39 | from box_sdk_gen.schemas.file import File |
|
38 | 42 |
|
39 | 43 | from box_sdk_gen.schemas.upload_part import UploadPart |
40 | 44 |
|
| 45 | +from box_sdk_gen.schemas.upload_part_plan import UploadPartPlan |
| 46 | + |
41 | 47 | from box_sdk_gen.schemas.upload_parts import UploadParts |
42 | 48 |
|
43 | 49 | from box_sdk_gen.schemas.uploaded_part import UploadedPart |
44 | 50 |
|
| 51 | +from box_sdk_gen.schemas.upload_session_plan_response import UploadSessionPlanResponse |
| 52 | + |
45 | 53 | from box_sdk_gen.schemas.files import Files |
46 | 54 |
|
47 | 55 | from box_sdk_gen.client import BoxClient |
@@ -253,6 +261,80 @@ def testChunkedManualProcessByUrl(): |
253 | 261 | client.chunked_uploads.delete_file_upload_session_by_url(abort_url) |
254 | 262 |
|
255 | 263 |
|
| 264 | +class _TestPartPlanAccumulator: |
| 265 | + def __init__(self, last_index: int, parts: List[UploadPartPlan], file_size: int): |
| 266 | + self.last_index = last_index |
| 267 | + self.parts = parts |
| 268 | + self.file_size = file_size |
| 269 | + |
| 270 | + |
| 271 | +def _reducer_for_upload_session_plan( |
| 272 | + acc: _TestPartPlanAccumulator, chunk: ByteStream |
| 273 | +) -> _TestPartPlanAccumulator: |
| 274 | + last_index: int = acc.last_index |
| 275 | + parts: List[UploadPartPlan] = acc.parts |
| 276 | + chunk_buffer: Buffer = read_byte_stream(chunk) |
| 277 | + hash: Hash = Hash(algorithm=HashName.SHA512) |
| 278 | + hash.update_hash(chunk_buffer) |
| 279 | + sha_512: str = hash.digest_hash('hex') |
| 280 | + chunk_size: int = buffer_length(chunk_buffer) |
| 281 | + bytes_start: int = last_index + 1 |
| 282 | + bytes_end: int = last_index + chunk_size |
| 283 | + part: UploadPartPlan = UploadPartPlan( |
| 284 | + offset=bytes_start, size=chunk_size, sha_512=sha_512 |
| 285 | + ) |
| 286 | + return _TestPartPlanAccumulator( |
| 287 | + last_index=bytes_end, parts=parts + [part], file_size=acc.file_size |
| 288 | + ) |
| 289 | + |
| 290 | + |
| 291 | +def testUploadSessionPlan(): |
| 292 | + file_size: int = (20 * 1024) * 1024 |
| 293 | + file_name: str = get_uuid() |
| 294 | + parent_folder_id: str = '0' |
| 295 | + file_content_stream: ByteStream = generate_byte_stream(file_size) |
| 296 | + file_buffer: Buffer = read_byte_stream(file_content_stream) |
| 297 | + uploaded_file: File = client.chunked_uploads.upload_big_file( |
| 298 | + generate_byte_stream_from_buffer(file_buffer), |
| 299 | + file_name, |
| 300 | + file_size, |
| 301 | + parent_folder_id, |
| 302 | + ) |
| 303 | + delay_in_seconds(5) |
| 304 | + upload_session: UploadSession = ( |
| 305 | + client.chunked_uploads.create_file_upload_session_for_existing_file( |
| 306 | + uploaded_file.id, file_size |
| 307 | + ) |
| 308 | + ) |
| 309 | + upload_session_id: str = upload_session.id |
| 310 | + plan_url: str = upload_session.session_endpoints.plan |
| 311 | + part_size: int = upload_session.part_size |
| 312 | + total_parts: int = upload_session.total_parts |
| 313 | + chunks_iterator: Iterator = iterate_chunks( |
| 314 | + generate_byte_stream_from_buffer(file_buffer), part_size, file_size |
| 315 | + ) |
| 316 | + results: _TestPartPlanAccumulator = reduce_iterator( |
| 317 | + chunks_iterator, |
| 318 | + _reducer_for_upload_session_plan, |
| 319 | + _TestPartPlanAccumulator(last_index=-1, parts=[], file_size=file_size), |
| 320 | + ) |
| 321 | + parts: List[UploadPartPlan] = results.parts |
| 322 | + plan: UploadSessionPlanResponse = ( |
| 323 | + client.chunked_uploads.create_file_upload_session_plan_by_url(plan_url, parts) |
| 324 | + ) |
| 325 | + assert plan.upload_session_id == upload_session_id |
| 326 | + assert len(plan.hits) == total_parts |
| 327 | + assert len(plan.misses) == 0 |
| 328 | + first_part: UploadPartPlan = parts[0] |
| 329 | + first_hit: UploadPartPlanHit = plan.hits[0] |
| 330 | + assert first_hit.offset == first_part.offset |
| 331 | + assert first_hit.size == first_part.size |
| 332 | + assert first_hit.sha_512 == first_part.sha_512 |
| 333 | + assert not first_hit.part_id == '' |
| 334 | + client.chunked_uploads.delete_file_upload_session_by_id(upload_session_id) |
| 335 | + client.files.delete_file_by_id(uploaded_file.id) |
| 336 | + |
| 337 | + |
256 | 338 | def testChunkedUploadConvenienceMethod(): |
257 | 339 | file_size: int = (20 * 1024) * 1024 |
258 | 340 | file_byte_stream: ByteStream = generate_byte_stream(file_size) |
|
0 commit comments