Bug 567736: [RJ-Server] Add unit tests for RService.uploadFile and
RService.downloadFile
Change-Id: If83e85f35220ba8575c5ffdb21ffa104a15c7853
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/AbstractLocalNodeTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/AbstractLocalNodeTest.java
new file mode 100644
index 0000000..7def5a7
--- /dev/null
+++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/AbstractLocalNodeTest.java
@@ -0,0 +1,105 @@
+/*=============================================================================#
+ # Copyright (c) 2020 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.rj.servi.pool;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.security.auth.login.LoginException;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.rmi.RMIRegistry;
+import org.eclipse.statet.jcommons.rmi.RMIRegistryManager;
+import org.eclipse.statet.jcommons.status.NullProgressMonitor;
+import org.eclipse.statet.jcommons.status.StatusException;
+
+import org.eclipse.statet.rj.server.util.RJContext;
+import org.eclipse.statet.rj.servi.RServi;
+import org.eclipse.statet.rj.servi.RServiUtils;
+import org.eclipse.statet.rj.servi.node.RServiImpl;
+import org.eclipse.statet.rj.servi.node.RServiNodeConfig;
+import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
+import org.eclipse.statet.rj.servi.node.RServiNodeManager;
+
+
+@NonNullByDefault
+public abstract class AbstractLocalNodeTest extends AbstractServiTest {
+
+
+ private final String name;
+
+ protected RServiNodeManager localR= nonNullLateInit();
+
+
+ public AbstractLocalNodeTest() throws Exception {
+ super();
+ this.name= getClass().getSimpleName();
+ }
+
+
+ @BeforeEach
+ public void initNode() throws Exception {
+ final RJContext context= ServiTests.getRJContext();
+ final RMIRegistry rmiRegistry= RMIRegistryManager.INSTANCE.getEmbeddedPrivateRegistry(
+ new NullProgressMonitor() );
+
+ final RServiNodeConfig nodeConfig= new RServiNodeConfig();
+ nodeConfig.load(getEnvConfiguration("default"));
+
+ final RServiNodeFactory nodeFactory= RServiImpl.createLocalNodeFactory(this.name, context);
+ nodeFactory.setRegistry(rmiRegistry);
+ nodeFactory.setConfig(nodeConfig);
+
+ this.localR= nonNullAssert(
+ RServiImpl.createNodeManager(this.name, rmiRegistry, nodeFactory) );
+ }
+
+ @AfterEach
+ public void dispose() throws Exception {
+ final List<Throwable> exceptions= new ArrayList<>();
+ disposeServis(exceptions);
+
+ final var localR= this.localR;
+ if (localR != null) {
+ try {
+ localR.stop();
+ }
+ catch (final Exception e) {
+ exceptions.add(e);
+ }
+ finally {
+ this.localR= nonNullLateInit();
+ }
+ }
+
+ reportErrors(exceptions);
+ }
+
+
+ protected RServi getServi(final String id)
+ throws NoSuchElementException, LoginException, StatusException {
+ final RServi servi= RServiUtils.getRServi(this.localR, id);
+ onServiGet(servi);
+ return servi;
+ }
+
+}
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java
index 60f8265..f4b3820 100644
--- a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java
+++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java
@@ -18,26 +18,17 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
-
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
import java.util.NoSuchElementException;
import javax.management.OperationsException;
import javax.security.auth.login.LoginException;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
-import org.eclipse.statet.jcommons.rmi.RMIRegistry;
-import org.eclipse.statet.jcommons.rmi.RMIRegistryManager;
import org.eclipse.statet.jcommons.status.NullProgressMonitor;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
@@ -46,73 +37,18 @@
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
-import org.eclipse.statet.rj.server.util.RJContext;
import org.eclipse.statet.rj.servi.RServi;
-import org.eclipse.statet.rj.servi.RServiUtils;
-import org.eclipse.statet.rj.servi.node.RServiImpl;
-import org.eclipse.statet.rj.servi.node.RServiNodeConfig;
-import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
-import org.eclipse.statet.rj.servi.node.RServiNodeManager;
@EnabledIfEnvironmentVariable(named= "STATET_TEST_FILES", matches= ".+")
@NonNullByDefault
-public class LocalNodeTest extends AbstractServiTest {
-
-
- private RServiNodeManager localR= nonNullLateInit();
+public class LocalNodeTest extends AbstractLocalNodeTest {
public LocalNodeTest() throws Exception {
}
- @BeforeEach
- public void initNode() throws Exception {
- final RJContext context= ServiTests.getRJContext();
- final RMIRegistry rmiRegistry= RMIRegistryManager.INSTANCE.getEmbeddedPrivateRegistry(
- new NullProgressMonitor() );
-
- final RServiNodeConfig nodeConfig= new RServiNodeConfig();
- nodeConfig.load(getEnvConfiguration("default"));
-
- final RServiNodeFactory nodeFactory= RServiImpl.createLocalNodeFactory(
- "LocalNodeTest", context );
- nodeFactory.setRegistry(rmiRegistry);
- nodeFactory.setConfig(nodeConfig);
-
- this.localR= nonNullAssert(
- RServiImpl.createNodeManager("LocalNodeTest", rmiRegistry, nodeFactory) );
- }
-
- @AfterEach
- public void dispose() throws Exception {
- final List<Throwable> exceptions= new ArrayList<>();
- disposeServis(exceptions);
-
- final var localR= this.localR;
- if (localR != null) {
- try {
- localR.stop();
- }
- catch (final Exception e) {
- exceptions.add(e);
- }
- finally {
- this.localR= nonNullLateInit();
- }
- }
-
- reportErrors(exceptions);
- }
-
- private RServi getServi(final String id) throws NoSuchElementException, LoginException, StatusException {
- final RServi servi= RServiUtils.getRServi(this.localR, id);
- onServiGet(servi);
- return servi;
- }
-
-
@Test
public void test1() throws RjException, OperationsException,
NoSuchElementException, LoginException, StatusException, UnexpectedRDataException {
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/service/tests/RServiceTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/service/tests/RServiceTest.java
new file mode 100644
index 0000000..473f6ef
--- /dev/null
+++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/service/tests/RServiceTest.java
@@ -0,0 +1,229 @@
+/*=============================================================================#
+ # Copyright (c) 2020 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.rj.servi.service.tests;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.status.NullProgressMonitor;
+import org.eclipse.statet.jcommons.status.ProgressMonitor;
+import org.eclipse.statet.jcommons.status.StatusException;
+
+import org.eclipse.statet.rj.data.RDataUtils;
+import org.eclipse.statet.rj.data.RObject;
+import org.eclipse.statet.rj.data.impl.DefaultRObjectFactory;
+import org.eclipse.statet.rj.servi.RServi;
+import org.eclipse.statet.rj.servi.pool.AbstractLocalNodeTest;
+
+
+@EnabledIfEnvironmentVariable(named= "STATET_TEST_FILES", matches= ".+")
+@NonNullByDefault
+public class RServiceTest extends AbstractLocalNodeTest {
+
+
+ private static Path tempDir= nonNullLateInit();
+
+
+ public RServiceTest() throws Exception {
+ }
+
+
+ @BeforeAll
+ public static void initTemp() throws IOException {
+ tempDir= Files.createTempDirectory("RServiceTest");
+ }
+
+
+ @BeforeEach
+ @Override
+ public void initNode() throws Exception {
+ super.initNode();
+ this.localR.start();
+ }
+
+
+ @Test
+ public void uploadFile_Stream() throws Exception {
+ final ProgressMonitor m= new NullProgressMonitor();
+ final RServi servi= getServi("uploadFile_Stream");
+
+ final byte[] content= "Hello World!".getBytes(StandardCharsets.UTF_8);
+ RObject rContentObj;
+
+ servi.uploadFile(new ByteArrayInputStream(content), content.length, "relative.txt", 0, m);
+ rContentObj= servi.createFunctionCall("readBin")
+ .addChar("con", "relative.txt")
+ .addInt("n", 100)
+ .addChar("what", "raw")
+ .evalData(m);
+ assertArrayEquals(content, RDataUtils.checkRRawVector(rContentObj).getData().toRawArray());
+
+ final var rwd= Path.of(RDataUtils.checkSingleCharValue(
+ servi.createFunctionCall("getwd").evalData(m) ));
+ servi.uploadFile(new ByteArrayInputStream(content), content.length,
+ rwd.resolve("absolute.txt").toString(), 0, m );
+ rContentObj= servi.createFunctionCall("readBin")
+ .addChar("con", "absolute.txt")
+ .addInt("n", 100)
+ .addChar("what", "raw")
+ .evalData(m);
+ assertArrayEquals(content, RDataUtils.checkRRawVector(rContentObj).getData().toRawArray());
+
+ assertThrows(StatusException.class, () -> {
+ servi.uploadFile(new ByteArrayInputStream(content), content.length,
+ "invalid://text.txt", 0, m );
+ });
+
+ assertThrows(StatusException.class, () -> {
+ servi.uploadFile(new ByteArrayInputStream(content), content.length + 1,
+ "toosmall.txt", 0, m );
+ });
+
+ closeServi(servi);
+ }
+
+ @Test
+ public void uploadFile_Example1() throws Exception {
+ final ProgressMonitor m= new NullProgressMonitor();
+ final RServi servi= getServi("uploadFile_Example1");
+
+ final byte[] content= "Hello World! - example1".getBytes(StandardCharsets.UTF_8);
+ final Path testFile= tempDir.resolve("uploadFile_Example1.txt");
+
+ Files.write(testFile, content);
+ try (final var in= Files.newInputStream(testFile)) {
+ servi.uploadFile(in, Files.size(testFile), "test.txt", 0, m);
+ }
+ final var rContent= servi.createFunctionCall("readBin")
+ .addChar("con", "test.txt")
+ .addInt("n", 100)
+ .addChar("what", "raw")
+ .evalData(m);
+ closeServi(servi);
+
+ assertArrayEquals(content, RDataUtils.checkRRawVector(rContent).getData().toRawArray());
+ }
+
+ @Test
+ public void downloadFile_Stream() throws Exception {
+ final ProgressMonitor m= new NullProgressMonitor();
+ final RServi servi= getServi("downloadFile_Stream");
+
+ final byte[] content= "Hello World! - example1".getBytes(StandardCharsets.UTF_8);
+ final ByteArrayOutputStream out= new ByteArrayOutputStream();
+
+ servi.createFunctionCall("writeBin")
+ .add(DefaultRObjectFactory.INSTANCE.createRawVector(content))
+ .addChar("con", "relative.txt").addLogi("useBytes", true)
+ .evalVoid(m);
+ out.reset();
+ servi.downloadFile(out, "relative.txt", 0, m);
+ assertArrayEquals(content, out.toByteArray());
+
+ final var rwd= Path.of(RDataUtils.checkSingleCharValue(
+ servi.createFunctionCall("getwd").evalData(m) ));
+ servi.createFunctionCall("writeBin")
+ .add(DefaultRObjectFactory.INSTANCE.createRawVector(content))
+ .addChar("con", "absolute.txt").addLogi("useBytes", true)
+ .evalVoid(m);
+ out.reset();
+ servi.downloadFile(out, rwd.resolve("absolute.txt").toString(), 0, m);
+ assertArrayEquals(content, out.toByteArray());
+
+ assertThrows(StatusException.class, () -> {
+ out.reset();
+ servi.downloadFile(out, "invalid://text.txt", 0, m);
+ });
+
+ assertThrows(StatusException.class, () -> {
+ out.reset();
+ servi.downloadFile(out, "missing.txt", 0, m);
+ });
+
+ closeServi(servi);
+ }
+
+ @Test
+ public void downloadFile_Array() throws Exception {
+ final ProgressMonitor m= new NullProgressMonitor();
+ final RServi servi= getServi("downloadFile_Stream");
+
+ final byte[] content= "Hello World! - example1".getBytes(StandardCharsets.UTF_8);
+ byte[] rContent;
+
+ servi.createFunctionCall("writeBin")
+ .add(DefaultRObjectFactory.INSTANCE.createRawVector(content))
+ .addChar("con", "relative.txt").addLogi("useBytes", true)
+ .evalVoid(m);
+ rContent= servi.downloadFile("relative.txt", 0, m);
+ assertArrayEquals(content, rContent);
+
+ final var rwd= Path.of(RDataUtils.checkSingleCharValue(
+ servi.createFunctionCall("getwd").evalData(m) ));
+ servi.createFunctionCall("writeBin")
+ .add(DefaultRObjectFactory.INSTANCE.createRawVector(content))
+ .addChar("con", "absolute.txt").addLogi("useBytes", true)
+ .evalVoid(m);
+ rContent= servi.downloadFile(rwd.resolve("absolute.txt").toString(), 0, m);
+ assertArrayEquals(content, rContent);
+
+ assertThrows(StatusException.class, () -> {
+ servi.downloadFile("invalid://text.txt", 0, m);
+ });
+
+ assertThrows(StatusException.class, () -> {
+ servi.downloadFile("missing.txt", 0, m);
+ });
+
+ closeServi(servi);
+ }
+
+ @Test
+ public void downloadFile_Example1() throws Exception {
+ final ProgressMonitor m= new NullProgressMonitor();
+ final RServi servi= getServi("downloadFile_Example1");
+
+ final byte[] content= "Hello World! - example1".getBytes(StandardCharsets.UTF_8);
+ final Path testFile= tempDir.resolve("downloadFile_Example1.txt");
+
+ servi.createFunctionCall("writeBin")
+ .add(DefaultRObjectFactory.INSTANCE.createRawVector(content))
+ .addChar("con", "test.txt").addLogi("useBytes", true)
+ .evalVoid(m);
+ try (final var out= Files.newOutputStream(testFile)) {
+ servi.downloadFile(out, "test.txt", 0, m);
+ }
+ closeServi(servi);
+ final var fileText= Files.readAllBytes(testFile);
+
+ assertArrayEquals(content, fileText);
+ }
+
+}