Skip to content

Commit d1975e9

Browse files
committed
API: Added many tests for batch downloading
Using mockito.
1 parent 113b92e commit d1975e9

5 files changed

Lines changed: 569 additions & 19 deletions

File tree

Cargo.lock

Lines changed: 164 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ rustc_version = "0.4.1"
6767

6868
# Testing
6969
tempfile = "3.19.1"
70+
mockito = "1.7.1"
7071

7172
[profile.release]
7273
strip = "debuginfo"

portablemc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ zip.workspace = true
4747

4848
[dev-dependencies]
4949
tempfile.workspace = true
50+
mockito.workspace = true

portablemc/src/download.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ async fn download_entry(
880880

881881
// Now we do all the allowed tries at downloading the file.
882882
let mut try_num = 0u8;
883-
let (size, sha1) = 'outer: loop {
883+
let (size, sha1) = 'success: loop {
884884

885885
let mut size = 0usize;
886886
let mut sha1 = Sha1::new();
@@ -889,16 +889,40 @@ async fn download_entry(
889889
// We specify if this error should be retried.
890890
let (retry, mut err) = loop {
891891

892+
// Read chunk by chunk, any error break the loop and fallthrough, retrying if
893+
// this is timeout or decode error.
892894
let chunk = match res.chunk().await {
893895
Ok(chunk) => chunk,
894896
Err(e) => break (e.is_timeout() || e.is_decode(), EntryErrorKind::new_reqwest(e)),
895897
};
896898

899+
// If chunk is none, it means that we finished reading, the file is complete
900+
// and so we check size and sha-1, on mismatch we don't retry!
897901
let Some(chunk) = chunk else {
898-
// We finished copying all chunks, return the size and sha1!
899-
break 'outer (size, sha1);
902+
903+
let Ok(size) = u32::try_from(size) else {
904+
break (false, EntryErrorKind::InvalidSize);
905+
};
906+
907+
let sha1 = sha1.finalize();
908+
909+
if let Some(expected_size) = entry.expected_size {
910+
if expected_size != size {
911+
break (false, EntryErrorKind::InvalidSize);
912+
}
913+
}
914+
915+
if let Some(expected_sha1) = &entry.expected_sha1 {
916+
if expected_sha1 != sha1.as_slice() {
917+
break (false, EntryErrorKind::InvalidSha1);
918+
}
919+
}
920+
921+
break 'success (size, sha1);
922+
900923
};
901924

925+
// Adding the size delta and transmit it to the progress handler.
902926
let delta = chunk.len();
903927
size += delta;
904928

@@ -959,27 +983,16 @@ async fn download_entry(
959983
// Remove the file, because we are not guaranteed that it's complete.
960984
// Ignore the error in case it fails, we just want to return the original error.
961985
let _ = fs::remove_file(&*entry.core.file).await;
986+
987+
// Also remove the cache file if the file is cached.
988+
if let Some(cache_file) = cache_file.as_deref() {
989+
let _ = fs::remove_file(cache_file).await;
990+
}
962991

963992
return Err(err);
964993

965994
};
966995

967-
// Now check required size and SHA-1.
968-
let size = u32::try_from(size).map_err(|_| EntryErrorKind::InvalidSize)?;
969-
let sha1 = sha1.finalize();
970-
971-
if let Some(expected_size) = entry.expected_size {
972-
if expected_size != size {
973-
return Err(EntryErrorKind::InvalidSize);
974-
}
975-
}
976-
977-
if let Some(expected_sha1) = &entry.expected_sha1 {
978-
if expected_sha1 != sha1.as_slice() {
979-
return Err(EntryErrorKind::InvalidSha1);
980-
}
981-
}
982-
983996
// If we have a cache file, write it.
984997
if let Some(cache_file) = cache_file.as_deref() {
985998

@@ -1014,6 +1027,7 @@ async fn download_entry(
10141027

10151028
file.flush().await.map_err(EntryErrorKind::new_io)?;
10161029

1030+
// At the end, handle the keep open option!
10171031
let handle;
10181032
if entry.keep_open {
10191033
let mut file = file.into_std().await;

0 commit comments

Comments
 (0)