Skip to content

Commit

Permalink
[LEIP-210] Fix error message on wrongly sized upload (#172)
Browse files Browse the repository at this point in the history
Also added a test to verify this in the future.
  • Loading branch information
muthenberg authored Mar 21, 2024
1 parent 9b0fb96 commit 8cf51f3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ class GoogleCloudStorageService(
val subscriber = CloudStorageSubscriber<Buffer>(cloud)

targetStream.subscribe(subscriber)
pipe.to(targetStream).onSuccess {
val pipeToProcess = pipe.to(targetStream)
pipeToProcess.onSuccess {
// if finished store the metadata to Mongo and delete the tmp file.
val bytesUploaded = cloud.bytesUploaded()
val contentRange = uploadMetaData.contentRange
Expand All @@ -76,7 +77,7 @@ class GoogleCloudStorageService(
ContentRangeNotMatchingFileSize(
String.format(
Locale.getDefault(),
"Response: 500, Content-Range ({}) not matching file size ({})",
"Response: 500, Content-Range (%s) not matching file size (%s)",
contentRange,
bytesUploaded
)
Expand All @@ -100,7 +101,8 @@ class GoogleCloudStorageService(
)
)
}
}.onFailure(ret::fail)
}
pipeToProcess.onFailure(ret::fail)

return ret.future()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package de.cyface.collector.storage.exception

import java.util.Objects

/**
* An `Exception` thrown when the provided content range of an uploaded file does not correspond to the content range,
* provided via the HTTP header.
Expand All @@ -26,4 +28,14 @@ package de.cyface.collector.storage.exception
* @version 1.0.1
* @constructor Provide an explanation for the error via the `format` parameter.
*/
class ContentRangeNotMatchingFileSize(format: String) : Exception(format)
class ContentRangeNotMatchingFileSize(format: String) : Exception(format) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ContentRangeNotMatchingFileSize) return false
return this.message == other.message
}

override fun hashCode(): Int {
return Objects.hash(javaClass.hashCode(), message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ import de.cyface.collector.model.RequestMetaData
import de.cyface.collector.model.User
import de.cyface.collector.storage.StatusType
import de.cyface.collector.storage.UploadMetaData
import de.cyface.collector.storage.exception.ContentRangeNotMatchingFileSize
import io.vertx.core.Future
import io.vertx.core.Handler
import io.vertx.core.Vertx
import io.vertx.core.buffer.Buffer
import io.vertx.core.streams.Pipe
import io.vertx.core.streams.WriteStream
import io.vertx.ext.reactivestreams.ReactiveWriteStream
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
Expand Down Expand Up @@ -210,6 +212,51 @@ class GoogleCloudStorageTest {
verify(mockStorage).delete(testDataFile)
}

/**
* Tests that uploading a file with a wrong size actually produces the correct error message.
*/
@Test
fun `A Mismatch between file size and content range should fail`() {
// Arrange
val database: Database = mock()
val vertx: Vertx = mock()
val mockCloudStorage: CloudStorage = mock {
on { bytesUploaded() } doReturn 4
}
val cloudStorageFactory: CloudStorageFactory = mock {
on { create(any<UUID>()) } doReturn mockCloudStorage
}
val oocut = GoogleCloudStorageService(database, vertx, cloudStorageFactory)
val mockToFuture: Future<Void> = mock()
val mockPipe: Pipe<Buffer> = mock {
on { to(any<WriteStream<Buffer>>()) } doReturn mockToFuture
}
val metadata: UploadMetaData = mock {
on { contentRange } doReturn ContentRange(5, 7, 3)
on { uploadIdentifier } doReturn UUID.randomUUID()
}

// Act
val result = oocut.store(mockPipe, metadata)

// Assert
argumentCaptor<Handler<Void>> {
verify(mockToFuture).onSuccess(capture())

firstValue.handle(null)
}
assertTrue(result.isComplete)
assertTrue(result.failed())
assertEquals(
ContentRangeNotMatchingFileSize(
"""
Response: 500, Content-Range (ContentRange(fromIndex=5, toIndex=7, totalBytes=3)) not matching file size (4)
""".trim()
),
result.cause(),
)
}

/**
* Provide some example metadata usable by tests.
*/
Expand Down

0 comments on commit 8cf51f3

Please sign in to comment.