diff --git a/library/src/androidTest/java/com/owncloud/android/AbstractIT.java b/library/src/androidTest/java/com/owncloud/android/AbstractIT.java index de9516071..390183d3b 100644 --- a/library/src/androidTest/java/com/owncloud/android/AbstractIT.java +++ b/library/src/androidTest/java/com/owncloud/android/AbstractIT.java @@ -60,6 +60,7 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.security.KeyStoreException; @@ -215,6 +216,38 @@ public String createFile(String name) throws IOException { return file.getAbsolutePath(); } + public String createFile(String name, int iteration) throws IOException { + File tempDir = context.getExternalCacheDir(); + + if (tempDir == null) { + throw new IOException("Temp dir is null"); + } + + if (!tempDir.exists()) { + if (!tempDir.mkdirs()) { + throw new IOException("Cannot create temp dir: " + tempDir.getAbsolutePath()); + } + } + + File file = new File(tempDir + File.separator + name); + + if (!file.exists() && !file.createNewFile()) { + throw new IOException("Cannot create file: " + file.getAbsolutePath()); + } + + assertTrue(file.exists()); + + FileWriter writer = new FileWriter(file); + + for (int i = 0; i < iteration; i++) { + writer.write("123123123123123123123123123\n"); + } + writer.flush(); + writer.close(); + + return file.getAbsolutePath(); + } + /** * Extracts file from AssetManager to cache folder. * @@ -278,4 +311,20 @@ public static File getFile(String filename) throws IOException { return temp; } + + protected void shortSleep() { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + protected void longSleep() { + try { + Thread.sleep(20000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } diff --git a/library/src/androidTest/java/com/owncloud/android/lib/resources/files/webdav/ChunkedFileUploadRemoteOperationIT.kt b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/webdav/ChunkedFileUploadRemoteOperationIT.kt new file mode 100644 index 000000000..6d8fb3fae --- /dev/null +++ b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/webdav/ChunkedFileUploadRemoteOperationIT.kt @@ -0,0 +1,97 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2023 Tobias Kaminsky + * Copyright (C) 2023 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.lib.resources.files.webdav + +import com.owncloud.android.AbstractIT +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode +import com.owncloud.android.lib.resources.files.ChunkedFileUploadRemoteOperation +import junit.framework.TestCase +import junit.framework.TestCase.assertNotNull +import junit.framework.TestCase.assertTrue +import org.junit.Test + +class ChunkedFileUploadRemoteOperationIT : AbstractIT() { + @Test + fun upload() { + // create file + val filePath = createFile("chunkedFile.txt", BIG_FILE_ITERATION) + val remotePath = "/bigFile.md" + + val sut = ChunkedFileUploadRemoteOperation( + filePath, + remotePath, + "text/markdown", + "", + RANDOM_MTIME, + System.currentTimeMillis() / MILLI_TO_SECOND, + true, + true + ) + + val uploadResult = sut.execute(client) + assertTrue(uploadResult.isSuccess) + } + + @Test + fun cancel() { + // create file + val filePath = createFile("chunkedFile.txt", BIG_FILE_ITERATION) + val remotePath = "/cancelFile.md" + + val sut = ChunkedFileUploadRemoteOperation( + filePath, + remotePath, + "text/markdown", + "", + RANDOM_MTIME, + System.currentTimeMillis() / MILLI_TO_SECOND, + false, + true + ) + + var uploadResult: RemoteOperationResult? = null + Thread { + uploadResult = sut.execute(client) + }.start() + + shortSleep() + sut.cancel(ResultCode.CANCELLED) + + for (i in 1..MAX_TRIES) { + shortSleep() + + if (uploadResult != null) { + break + } + } + + assertNotNull(uploadResult) + TestCase.assertFalse(uploadResult?.isSuccess == true) + TestCase.assertSame(ResultCode.CANCELLED, uploadResult?.code) + } + + companion object { + val BIG_FILE_ITERATION = 500000 + val MAX_TRIES = 30 + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java index 6d93a9f21..b71fd32e2 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java @@ -222,7 +222,13 @@ protected RemoteOperationResult run(OwnCloudClient client) { result = new RemoteOperationResult(isSuccess(moveResult), moveMethod); } catch (Exception e) { - if (moveMethod != null && moveMethod.isAborted()) { + if (putMethod != null && putMethod.isAborted()) { + if (cancellationRequested.get() && cancellationReason != null) { + result = new RemoteOperationResult(cancellationReason); + } else { + result = new RemoteOperationResult(new OperationCancelledException()); + } + } else if (moveMethod != null && moveMethod.isAborted()) { if (cancellationRequested.get() && cancellationReason != null) { result = new RemoteOperationResult(cancellationReason); } else {