diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/META-INF/MANIFEST.MF b/bundles/core/org.eclipse.smarthome.core.audio.test/META-INF/MANIFEST.MF
index 39be6750418..bf08558cb6d 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/META-INF/MANIFEST.MF
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/META-INF/MANIFEST.MF
@@ -12,12 +12,14 @@ Import-Package:
org.eclipse.jetty.client.api,
org.eclipse.jetty.http,
org.eclipse.jetty.io,
+ org.eclipse.jetty.servlet,
org.eclipse.jetty.util.component,
- org.eclipse.smarthome.test,
- org.eclipse.smarthome.test.java,
org.eclipse.smarthome.io.console,
org.eclipse.smarthome.io.console.extensions,
+ org.eclipse.smarthome.test,
+ org.eclipse.smarthome.test.java,
org.hamcrest;core=split,
org.junit,
- org.osgi.framework
+ org.mockito,
+ org.mockito.stubbing
Automatic-Module-Name: org.eclipse.smarthome.core.audio.test
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/org.eclipse.smarthome.core.audio.test.launch b/bundles/core/org.eclipse.smarthome.core.audio.test/org.eclipse.smarthome.core.audio.test.launch
index 195c2c93e06..6a216393d34 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/org.eclipse.smarthome.core.audio.test.launch
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/org.eclipse.smarthome.core.audio.test.launch
@@ -34,9 +34,9 @@
-
-
-
+
+
+
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AbstractAudioServeltTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AbstractAudioServeltTest.java
new file mode 100644
index 00000000000..7b8b4be9fc9
--- /dev/null
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AbstractAudioServeltTest.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.smarthome.core.audio.internal;
+
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.smarthome.core.audio.AudioFormat;
+import org.eclipse.smarthome.core.audio.AudioStream;
+import org.eclipse.smarthome.core.audio.ByteArrayAudioStream;
+import org.eclipse.smarthome.core.audio.FixedLengthAudioStream;
+import org.eclipse.smarthome.test.TestPortUtil;
+import org.eclipse.smarthome.test.TestServer;
+import org.eclipse.smarthome.test.java.JavaTest;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * Base class for tests using the {@link AudioServlet}.
+ *
+ * @author Henning Treu - initial contribution
+ *
+ */
+public abstract class AbstractAudioServeltTest extends JavaTest {
+
+ protected AudioServlet audioServlet;
+
+ private int port;
+ private TestServer server;
+
+ private final static String AUDIO_SERVLET_PROTOCOL = "http";
+ private final static String AUDIO_SERVLET_HOSTNAME = "localhost";
+
+ private CompletableFuture serverStarted;
+
+ private HttpClient httpClient;
+
+ @Before
+ public void setupServerAndClient() {
+ audioServlet = new AudioServlet();
+
+ ServletHolder servletHolder = new ServletHolder(audioServlet);
+
+ port = TestPortUtil.findFreePort();
+ server = new TestServer(AUDIO_SERVLET_HOSTNAME, port, 10000, servletHolder);
+ serverStarted = server.startServer();
+
+ httpClient = new HttpClient();
+ }
+
+ @After
+ public void tearDownServerAndClient() throws Exception {
+ server.stopServer();
+ httpClient.stop();
+ }
+
+ protected ByteArrayAudioStream getByteArrayAudioStream(byte[] byteArray, String container, String codec) {
+ int bitDepth = 16;
+ int bitRate = 1000;
+ long frequency = 16384;
+
+ AudioFormat audioFormat = new AudioFormat(container, codec, true, bitDepth, bitRate, frequency);
+
+ return new ByteArrayAudioStream(byteArray, audioFormat);
+ }
+
+ protected ContentResponse getHttpResponse(AudioStream audioStream) throws Exception {
+ String url = serveStream(audioStream);
+ return getHttpRequest(url).send();
+ }
+
+ protected String serveStream(AudioStream stream) throws Exception {
+ return serveStream(stream, null);
+ }
+
+ protected void startHttpClient(HttpClient client) {
+ if (!client.isStarted()) {
+ try {
+ client.start();
+ } catch (Exception e) {
+ fail("An exception " + e + " was thrown, while starting the HTTP client");
+ }
+ }
+ }
+
+ protected Request getHttpRequest(String url) {
+ startHttpClient(httpClient);
+ return httpClient.newRequest(url).method(HttpMethod.GET);
+ }
+
+ protected String serveStream(AudioStream stream, Integer timeInterval) throws Exception {
+ serverStarted.get(); // wait for the server thread to be started
+
+ String path;
+ if (timeInterval != null) {
+ path = audioServlet.serve((FixedLengthAudioStream) stream, timeInterval);
+ } else {
+ path = audioServlet.serve(stream);
+ }
+
+ return generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, port, path);
+ }
+
+ private String generateURL(String protocol, String hostname, int port, String path) {
+ return String.format("%s://%s:%s%s", protocol, hostname, port, path);
+ }
+
+}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioConsoleTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioConsoleTest.java
index 75ea726b9f4..2dad7357f73 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioConsoleTest.java
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioConsoleTest.java
@@ -14,15 +14,23 @@
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.*;
+import java.io.File;
+import java.io.IOException;
import java.util.Locale;
+import org.eclipse.smarthome.config.core.ConfigConstants;
import org.eclipse.smarthome.core.audio.AudioException;
import org.eclipse.smarthome.core.audio.AudioFormat;
-import org.eclipse.smarthome.core.audio.FixedLengthAudioStream;
+import org.eclipse.smarthome.core.audio.AudioSource;
+import org.eclipse.smarthome.core.audio.AudioStream;
+import org.eclipse.smarthome.core.audio.FileAudioStream;
import org.eclipse.smarthome.core.audio.URLAudioStream;
+import org.eclipse.smarthome.core.audio.internal.fake.AudioSinkFake;
+import org.eclipse.smarthome.core.i18n.LocaleProvider;
import org.eclipse.smarthome.io.console.Console;
-import org.eclipse.smarthome.io.console.extensions.ConsoleCommandExtension;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -33,11 +41,26 @@
* @author Christoph Weitkamp - Added parameter to adjust the volume
* @author Wouter Born - Migrate tests from Groovy to Java
*/
-public class AudioConsoleTest extends AudioOSGiTest {
+public class AudioConsoleTest extends AbstractAudioServeltTest {
+
private AudioConsoleCommandExtension audioConsoleCommandExtension;
+ private AudioManagerImpl audioManager;
+
+ private AudioSinkFake audioSink;
+
+ private final byte[] testByteArray = new byte[] { 0, 1, 2 };
+
+ private static final String CONFIGURATION_DIRECTORY_NAME = "configuration";
+
+ protected static final String MP3_FILE_NAME = "mp3AudioFile.mp3";
+ protected static final String MP3_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + MP3_FILE_NAME;
+
+ protected static final String WAV_FILE_NAME = "wavAudioFile.wav";
+ protected static final String WAV_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + WAV_FILE_NAME;
+
private String consoleOutput;
- private Console consoleMock = new Console() {
+ private final Console consoleMock = new Console() {
@Override
public void println(String s) {
@@ -54,49 +77,72 @@ public void print(String s) {
}
};
- private int testTimeout = 1;
+ private final int testTimeout = 1;
- @Override
@Before
public void setUp() {
- registerSink();
- audioConsoleCommandExtension = getAudioConsoleCommandExtension();
+ audioManager = new AudioManagerImpl();
+ audioSink = new AudioSinkFake();
+ audioManager.addAudioSink(audioSink);
+
+ audioConsoleCommandExtension = new AudioConsoleCommandExtension();
+ audioConsoleCommandExtension.setAudioManager(audioManager);
+
+ LocaleProvider localeProvider = mock(LocaleProvider.class);
+ when(localeProvider.getLocale()).thenReturn(Locale.getDefault());
+ audioConsoleCommandExtension.setLocaleProvider(localeProvider);
+
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, CONFIGURATION_DIRECTORY_NAME);
+ }
+
+ @After
+ public void tearDown() {
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, ConfigConstants.DEFAULT_CONFIG_FOLDER);
}
@Test
- public void audioConsolePlaysFile() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
+ public void testUsages() {
+ assertThat("Could not get AudioConsoleCommandExtension's usages", audioConsoleCommandExtension.getUsages(),
+ is(notNullValue()));
+ }
+
+ @Test
+ public void audioConsolePlaysFile() throws AudioException, IOException {
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, WAV_FILE_NAME };
audioConsoleCommandExtension.execute(args, consoleMock);
- assertCompatibleFormat();
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
+ audioStream.close();
}
@Test
- public void audioConsolePlaysFileForASpecifiedSink() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
+ public void audioConsolePlaysFileForASpecifiedSink() throws AudioException, IOException {
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
- String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSinkFake.getId(), WAV_FILE_NAME };
+ String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSink.getId(), WAV_FILE_NAME };
audioConsoleCommandExtension.execute(args, consoleMock);
- assertCompatibleFormat();
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
+ audioStream.close();
}
@Test
- public void audioConsolePlaysFileForASpecifiedSinkWithASpecifiedVolume() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
+ public void audioConsolePlaysFileForASpecifiedSinkWithASpecifiedVolume() throws AudioException, IOException {
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
- String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSinkFake.getId(), WAV_FILE_NAME,
+ String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSink.getId(), WAV_FILE_NAME,
"25" };
audioConsoleCommandExtension.execute(args, consoleMock);
- assertCompatibleFormat();
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
+ audioStream.close();
}
@Test
public void audioConsolePlaysFileForASpecifiedSinkWithAnInvalidVolume() {
- String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSinkFake.getId(), WAV_FILE_NAME,
+ String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_PLAY, audioSink.getId(), WAV_FILE_NAME,
"invalid" };
audioConsoleCommandExtension.execute(args, consoleMock);
@@ -104,35 +150,29 @@ public void audioConsolePlaysFileForASpecifiedSinkWithAnInvalidVolume() {
}
@Test
- public void audioConsolePlaysStream() {
- initializeAudioServlet();
-
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_PCM_SIGNED);
+ public void audioConsolePlaysStream() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_WAVE,
+ AudioFormat.CODEC_PCM_SIGNED);
- String path = audioServlet.serve((FixedLengthAudioStream) audioStream, testTimeout);
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
+ String url = serveStream(audioStream, testTimeout);
String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_STREAM, url };
audioConsoleCommandExtension.execute(args, consoleMock);
- assertThat("The streamed URL was not as expected", ((URLAudioStream) audioSinkFake.audioStream).getURL(),
- is(url));
+ assertThat("The streamed URL was not as expected", ((URLAudioStream) audioSink.audioStream).getURL(), is(url));
}
@Test
- public void audioConsolePlaysStreamForASpecifiedSink() {
- initializeAudioServlet();
-
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_PCM_SIGNED);
+ public void audioConsolePlaysStreamForASpecifiedSink() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_WAVE,
+ AudioFormat.CODEC_PCM_SIGNED);
- String path = audioServlet.serve((FixedLengthAudioStream) audioStream, testTimeout);
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
+ String url = serveStream(audioStream, testTimeout);
- String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_STREAM, audioSinkFake.getId(), url };
+ String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_STREAM, audioSink.getId(), url };
audioConsoleCommandExtension.execute(args, consoleMock);
- assertThat("The streamed URL was not as expected", ((URLAudioStream) audioSinkFake.audioStream).getURL(),
- is(url));
+ assertThat("The streamed URL was not as expected", ((URLAudioStream) audioSink.audioStream).getURL(), is(url));
}
@Test
@@ -141,28 +181,20 @@ public void audioConsoleListsSinks() {
audioConsoleCommandExtension.execute(args, consoleMock);
waitForAssert(() -> assertThat("The listed sink was not as expected", consoleOutput,
- is(String.format("* %s (%s)", audioSinkFake.getLabel(Locale.getDefault()), audioSinkFake.getId()))));
+ is(String.format("* %s (%s)", audioSink.getLabel(Locale.getDefault()), audioSink.getId()))));
}
@Test
public void audioConsoleListsSources() {
- registerSource();
+ AudioSource audioSource = mock(AudioSource.class);
+ when(audioSource.getId()).thenReturn("sourceId");
+ audioManager.addAudioSource(audioSource);
String[] args = new String[] { AudioConsoleCommandExtension.SUBCMD_SOURCES };
audioConsoleCommandExtension.execute(args, consoleMock);
- waitForAssert(() -> assertThat("The listed source was not as expected", consoleOutput, is(
- String.format("* %s (%s)", audioSourceMock.getLabel(Locale.getDefault()), audioSourceMock.getId()))));
- }
-
- protected AudioConsoleCommandExtension getAudioConsoleCommandExtension() {
- audioConsoleCommandExtension = getService(ConsoleCommandExtension.class, AudioConsoleCommandExtension.class);
-
- assertThat("Could not get AudioConsoleCommandExtension", audioConsoleCommandExtension, is(notNullValue()));
- assertThat("Could not get AudioConsoleCommandExtension's usages", audioConsoleCommandExtension.getUsages(),
- is(notNullValue()));
-
- return audioConsoleCommandExtension;
+ waitForAssert(() -> assertThat("The listed source was not as expected", consoleOutput,
+ is(String.format("* %s (%s)", audioSource.getLabel(Locale.getDefault()), audioSource.getId()))));
}
}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioFormatTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioFormatTest.java
index 962990b534f..33ccc33735a 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioFormatTest.java
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioFormatTest.java
@@ -27,13 +27,13 @@
* @author Petar Valchev - Initial contribution
* @author Wouter Born - Migrate tests from Groovy to Java
*/
-public class AudioFormatTest extends AudioOSGiTest {
- private String testContainer = AudioFormat.CONTAINER_WAVE;
- private String testCodec = AudioFormat.CODEC_PCM_SIGNED;
- private boolean testBigEndian = true;
- private Integer testBitDepth = new Integer(16);
- private Integer testBitRate = new Integer(1000);
- private Long testFrequency = new Long(1024);
+public class AudioFormatTest {
+ private final String testContainer = AudioFormat.CONTAINER_WAVE;
+ private final String testCodec = AudioFormat.CODEC_PCM_SIGNED;
+ private final boolean testBigEndian = true;
+ private final Integer testBitDepth = new Integer(16);
+ private final Integer testBitRate = new Integer(1000);
+ private final Long testFrequency = new Long(1024);
@Test
public void thereIsNoBestMatchForAnAudioFormatIfOneOfTheFieldsIsNull() {
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerServletTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerServletTest.java
new file mode 100644
index 00000000000..f00bffd5c97
--- /dev/null
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerServletTest.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.smarthome.core.audio.internal;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.smarthome.core.audio.AudioFormat;
+import org.eclipse.smarthome.core.audio.AudioStream;
+import org.eclipse.smarthome.core.audio.ByteArrayAudioStream;
+import org.eclipse.smarthome.core.audio.URLAudioStream;
+import org.eclipse.smarthome.core.audio.internal.fake.AudioSinkFake;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * OSGi test for {@link AudioManagerImpl}
+ *
+ * @author Petar Valchev - Initial contribution and API
+ * @author Christoph Weitkamp - Added parameter to adjust the volume
+ * @author Wouter Born - Migrate tests from Groovy to Java
+ * @author Henning Treu - extract servlet tests
+ */
+public class AudioManagerServletTest extends AbstractAudioServeltTest {
+
+ private AudioManagerImpl audioManager;
+
+ private AudioSinkFake audioSink;
+
+ @Before
+ public void setup() {
+ audioManager = new AudioManagerImpl();
+ audioSink = new AudioSinkFake();
+ }
+
+ @Test
+ public void audioManagerProcessesMultitimeStreams() throws Exception {
+ audioManager.addAudioSink(audioSink);
+ int streamTimeout = 10;
+ assertServedStream(streamTimeout);
+ }
+
+ @Test
+ public void audioManagerProcessesOneTimeStream() throws Exception {
+ audioManager.addAudioSink(audioSink);
+ assertServedStream(null);
+ }
+
+ @Test
+ public void audioManagerDoesNotProcessStreamsIfThereIsNoRegisteredSink() throws Exception {
+ int streamTimeout = 10;
+ assertServedStream(streamTimeout);
+ }
+
+ private void assertServedStream(Integer timeInterval) throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_PCM_SIGNED);
+ String url = serveStream(audioStream, timeInterval);
+
+ audioManager.stream(url, audioSink.getId());
+
+ if (audioManager.getSink() == audioSink) {
+ assertThat("The streamed url was not as expected", ((URLAudioStream) audioSink.audioStream).getURL(),
+ is(url));
+ } else {
+ assertThat(String.format("The sink %s received an unexpected stream", audioSink.getId()),
+ audioSink.audioStream, is(nullValue()));
+ }
+ }
+
+ private ByteArrayAudioStream getByteArrayAudioStream(String container, String codec) {
+ int bitDepth = 16;
+ int bitRate = 1000;
+ long frequency = 16384;
+ byte[] testByteArray = new byte[] { 0, 1, 2 };
+
+ AudioFormat audioFormat = new AudioFormat(container, codec, true, bitDepth, bitRate, frequency);
+
+ return new ByteArrayAudioStream(testByteArray, audioFormat);
+ }
+
+}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerTest.java
index 5e46d5c8e4a..b6d973b366c 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerTest.java
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioManagerTest.java
@@ -12,9 +12,10 @@
*/
package org.eclipse.smarthome.core.audio.internal;
-import static org.eclipse.smarthome.core.audio.internal.AudioManagerImpl.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
import java.io.File;
import java.io.IOException;
@@ -24,16 +25,19 @@
import java.util.Locale;
import java.util.function.BiFunction;
+import org.eclipse.smarthome.config.core.ConfigConstants;
import org.eclipse.smarthome.config.core.ParameterOption;
import org.eclipse.smarthome.core.audio.AudioException;
import org.eclipse.smarthome.core.audio.AudioFormat;
+import org.eclipse.smarthome.core.audio.AudioSource;
import org.eclipse.smarthome.core.audio.AudioStream;
-import org.eclipse.smarthome.core.audio.FixedLengthAudioStream;
-import org.eclipse.smarthome.core.audio.URLAudioStream;
-import org.eclipse.smarthome.core.audio.UnsupportedAudioFormatException;
+import org.eclipse.smarthome.core.audio.ByteArrayAudioStream;
+import org.eclipse.smarthome.core.audio.FileAudioStream;
import org.eclipse.smarthome.core.audio.UnsupportedAudioStreamException;
import org.eclipse.smarthome.core.audio.internal.fake.AudioSinkFake;
import org.eclipse.smarthome.core.library.types.PercentType;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
/**
@@ -42,86 +46,127 @@
* @author Petar Valchev - Initial contribution and API
* @author Christoph Weitkamp - Added parameter to adjust the volume
* @author Wouter Born - Migrate tests from Groovy to Java
+ * @author Henning Treu - Convert to plain java tests
*/
-public class AudioManagerTest extends AudioOSGiTest {
+public class AudioManagerTest {
+
+ private AudioManagerImpl audioManager;
+
+ private AudioSinkFake audioSink;
+ private AudioSource audioSource;
+
+ private static final String CONFIGURATION_DIRECTORY_NAME = "configuration";
+
+ private static final String MP3_FILE_NAME = "mp3AudioFile.mp3";
+ private static final String MP3_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + MP3_FILE_NAME;
+
+ private static final String WAV_FILE_NAME = "wavAudioFile.wav";
+ private static final String WAV_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + WAV_FILE_NAME;
+
+ @Before
+ public void setup() {
+ audioManager = new AudioManagerImpl();
+ audioSink = new AudioSinkFake();
+
+ audioSource = mock(AudioSource.class);
+ when(audioSource.getId()).thenReturn("audioSourceId");
+ when(audioSource.getLabel(any(Locale.class))).thenReturn("audioSourceLabel");
+
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, CONFIGURATION_DIRECTORY_NAME);
+ }
+
+ @After
+ public void tearDown() {
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, ConfigConstants.DEFAULT_CONFIG_FOLDER);
+ }
@Test
public void audioManagerPlaysByteArrayAudioStream() throws AudioException {
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_MP3);
- assertProcessedStreamTypeStream(audioStream);
+ audioManager.addAudioSink(audioSink);
+ ByteArrayAudioStream audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_MP3);
+
+ audioManager.play(audioStream, audioSink.getId());
+
+ AudioFormat expectedAudioFormat = audioStream.getFormat();
+
+ assertThat(audioSink.audioFormat.isCompatible(expectedAudioFormat), is(true));
}
@Test
public void nullStreamsAreProcessed() {
- registerSink();
-
- audioManager.play(null, audioSinkFake.getId());
+ audioManager.addAudioSink(audioSink);
+ audioManager.play(null, audioSink.getId());
- waitForAssert(
- () -> assertThat("The 'null' stream was not processed", audioSinkFake.isStreamProcessed, is(true)));
- assertThat("The currently playing stream was not stopped", audioSinkFake.isStreamStopped, is(true));
+ assertThat(audioSink.isStreamProcessed, is(true));
+ assertThat(audioSink.isStreamStopped, is(true));
}
@Test
public void audioManagerPlaysStreamFromWavAudioFiles() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
- assertProcessedStreamTypeStream(audioStream);
+ audioManager.addAudioSink(audioSink);
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
+
+ audioManager.play(audioStream, audioSink.getId());
+
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
}
@Test
public void audioManagerPlaysStreamFromMp3AudioFiles() throws AudioException {
- audioStream = getFileAudioStream(MP3_FILE_PATH);
- assertProcessedStreamTypeStream(audioStream);
+ audioManager.addAudioSink(audioSink);
+ AudioStream audioStream = new FileAudioStream(new File(MP3_FILE_PATH));
+
+ audioManager.play(audioStream, audioSink.getId());
+
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
}
@Test
- public void audioManagerPlaysWavAudioFiles() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
- assertProcessedStreamTypeFile(WAV_FILE_NAME);
+ public void audioManagerPlaysWavAudioFiles() throws AudioException, IOException {
+ audioManager.addAudioSink(audioSink);
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
+ audioManager.playFile(WAV_FILE_NAME, audioSink.getId());
+
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
+ audioStream.close();
}
@Test
- public void audioManagerPlaysMp3AudioFiles() throws AudioException {
- audioStream = getFileAudioStream(MP3_FILE_PATH);
- assertProcessedStreamTypeFile(MP3_FILE_NAME);
+ public void audioManagerPlaysMp3AudioFiles() throws AudioException, IOException {
+ audioManager.addAudioSink(audioSink);
+ AudioStream audioStream = new FileAudioStream(new File(MP3_FILE_PATH));
+ audioManager.playFile(MP3_FILE_NAME, audioSink.getId());
+
+ assertThat(audioSink.audioFormat.isCompatible(audioStream.getFormat()), is(true));
+ audioStream.close();
}
@Test
public void fileIsNotProcessedIfThereIsNoRegisteredSink() throws AudioException {
File file = new File(MP3_FILE_PATH);
- assertThat(String.format("The file %s does not exist", file.getName()), file.exists(), is(true));
- audioSinkFake = new AudioSinkFake();
+ audioManager.playFile(file.getName(), audioSink.getId());
- audioManager.playFile(file.getName(), audioSinkFake.getId());
-
- waitForAssert(() -> assertThat(String.format("The file %s was processed", file.getName()),
- audioSinkFake.isStreamProcessed, is(false)));
+ assertThat(audioSink.isStreamProcessed, is(false));
}
@Test
public void audioManagerHandlesUnsupportedAudioFormatException() throws AudioException {
- registerSink();
-
- audioStream = getFileAudioStream(MP3_FILE_PATH);
-
- audioSinkFake.isUnsupportedAudioFormatExceptionExpected = true;
+ audioManager.addAudioSink(audioSink);
+ audioSink.isUnsupportedAudioFormatExceptionExpected = true;
try {
- audioManager.playFile(MP3_FILE_NAME, audioSinkFake.getId());
- } catch (UnsupportedAudioFormatException e) {
+ audioManager.playFile(MP3_FILE_NAME, audioSink.getId());
+ } catch (UnsupportedAudioStreamException e) {
fail("An exception " + e + " was thrown, while trying to process a stream");
}
}
@Test
public void audioManagerHandlesUnsupportedAudioStreamException() throws AudioException {
- registerSink();
-
- audioStream = getFileAudioStream(MP3_FILE_PATH);
-
- audioSinkFake.isUnsupportedAudioStreamExceptionExpected = true;
+ audioManager.addAudioSink(audioSink);
+ audioSink.isUnsupportedAudioStreamExceptionExpected = true;
try {
- audioManager.playFile(MP3_FILE_NAME, audioSinkFake.getId());
+ audioManager.playFile(MP3_FILE_NAME, audioSink.getId());
} catch (UnsupportedAudioStreamException e) {
fail("An exception " + e + " was thrown, while trying to process a stream");
}
@@ -129,31 +174,24 @@ public void audioManagerHandlesUnsupportedAudioStreamException() throws AudioExc
@Test
public void audioManagerSetsTheVolumeOfASink() throws IOException {
- registerSink();
-
+ audioManager.addAudioSink(audioSink);
PercentType initialVolume = new PercentType(67);
PercentType sinkMockVolume = getSinkMockVolume(initialVolume);
- waitForAssert(
- () -> assertThat(String.format("The volume of the sink %s was not as expected", audioSinkFake.getId()),
- sinkMockVolume, is(initialVolume)));
+ assertThat(sinkMockVolume, is(initialVolume));
}
@Test
public void theVolumeOfANullSinkIsZero() throws IOException {
- assertThat("The volume was not as expected", audioManager.getVolume(null), is(PercentType.ZERO));
+ assertThat(audioManager.getVolume(null), is(PercentType.ZERO));
}
@Test
public void audioManagerSetsTheVolumeOfNotRegisteredSinkToZero() throws IOException {
- audioSinkFake = new AudioSinkFake();
-
PercentType initialVolume = new PercentType(67);
PercentType sinkMockVolume = getSinkMockVolume(initialVolume);
- waitForAssert(
- () -> assertThat(String.format("The volume of the sink %s was not as expected", audioSinkFake.getId()),
- sinkMockVolume, is(PercentType.ZERO)));
+ assertThat(sinkMockVolume, is(PercentType.ZERO));
}
@Test
@@ -188,98 +226,54 @@ public void sourceIsAddedInParameterOptions() {
@Test
public void inCaseOfWrongUriNoParameterOptionsAreAdded() {
- registerSink();
+ audioManager.addAudioSink(audioSink);
Collection parameterOptions = audioManager.getParameterOptions(URI.create("wrong.uri"),
AudioManagerImpl.CONFIG_DEFAULT_SINK, Locale.US);
assertThat("The parameter options were not as expected", parameterOptions, is(nullValue()));
}
- @Test
- public void audioManagerProcessesMultitimeStreams() throws AudioException {
- registerSink();
- int streamTimeout = 10;
- assertServedStream(streamTimeout);
- }
-
- @Test
- public void audioManagerProcessesOneTimeStream() throws AudioException {
- registerSink();
- assertServedStream(null);
- }
-
- @Test
- public void audioManagerDoesNotProcessStreamsIfThereIsNoRegisteredSink() throws AudioException {
- audioSinkFake = new AudioSinkFake();
- int streamTimeout = 10;
- assertServedStream(streamTimeout);
- }
-
private void assertRegisteredSource(boolean isSourceDefault) {
- registerSource();
+ audioManager.addAudioSource(audioSource);
if (isSourceDefault) {
- audioManager.modified(Collections.singletonMap(CONFIG_DEFAULT_SOURCE, audioSourceMock.getId()));
+ audioManager
+ .modified(Collections.singletonMap(AudioManagerImpl.CONFIG_DEFAULT_SOURCE, audioSource.getId()));
} else {
// just to make sure there is no default source
audioManager.modified(Collections.emptyMap());
}
- assertThat(String.format("The source %s was not registered", audioSourceMock.getId()), audioManager.getSource(),
- is(audioSourceMock));
- assertThat(String.format("The source %s was not added to the set of sources", audioSourceMock.getId()),
- audioManager.getAllSources().contains(audioSourceMock), is(true));
- assertThat(String.format("The source %s was not added to the set of sources", audioSourceMock.getId()),
- audioManager.getSourceIds(audioSourceMock.getId()).contains(audioSourceMock.getId()), is(true));
+ assertThat(String.format("The source %s was not registered", audioSource.getId()), audioManager.getSource(),
+ is(audioSource));
+ assertThat(String.format("The source %s was not added to the set of sources", audioSource.getId()),
+ audioManager.getAllSources().contains(audioSource), is(true));
+ assertThat(String.format("The source %s was not added to the set of sources", audioSource.getId()),
+ audioManager.getSourceIds(audioSource.getId()).contains(audioSource.getId()), is(true));
}
private void assertRegisteredSink(boolean isSinkDefault) {
- registerSink();
+ audioManager.addAudioSink(audioSink);
if (isSinkDefault) {
- audioManager.modified(Collections.singletonMap(CONFIG_DEFAULT_SINK, audioSinkFake.getId()));
+ audioManager.modified(Collections.singletonMap(AudioManagerImpl.CONFIG_DEFAULT_SINK, audioSink.getId()));
} else {
// just to make sure there is no default sink
audioManager.modified(Collections.emptyMap());
}
- assertThat(String.format("The sink %s was not registered", audioSinkFake.getId()), audioManager.getSink(),
- is(audioSinkFake));
- assertThat(String.format("The sink %s was not added to the set of sinks", audioSinkFake.getId()),
- audioManager.getAllSinks().contains(audioSinkFake), is(true));
- assertThat(String.format("The sink %s was not added to the set of sinks", audioSinkFake.getId()),
- audioManager.getSinkIds(audioSinkFake.getId()).contains(audioSinkFake.getId()), is(true));
- }
-
- private void assertProcessedStreamTypeStream(AudioStream audioStream) throws AudioException {
- registerSink();
-
- waitForAssert(() -> assertThat("The format of the audio sink mock was not as expected",
- audioSinkFake.audioFormat, is(nullValue())));
-
- assertThat("The currently playing stream was stopped", audioSinkFake.isStreamStopped, is(false));
- audioManager.play(audioStream, audioSinkFake.getId());
-
- assertCompatibleFormat();
- }
-
- private void assertProcessedStreamTypeFile(String audioFileName) throws AudioException {
- registerSink();
-
- waitForAssert(() -> assertThat("The format of the audio sink mock was not as expected",
- audioSinkFake.audioFormat, is(nullValue())));
-
- assertThat("The currently playing stream was stopped", audioSinkFake.isStreamStopped, is(false));
-
- audioManager.playFile(audioFileName, audioSinkFake.getId());
-
- assertCompatibleFormat();
+ assertThat(String.format("The sink %s was not registered", audioSink.getId()), audioManager.getSink(),
+ is(audioSink));
+ assertThat(String.format("The sink %s was not added to the set of sinks", audioSink.getId()),
+ audioManager.getAllSinks().contains(audioSink), is(true));
+ assertThat(String.format("The sink %s was not added to the set of sinks", audioSink.getId()),
+ audioManager.getSinkIds(audioSink.getId()).contains(audioSink.getId()), is(true));
}
private PercentType getSinkMockVolume(PercentType initialVolume) throws IOException {
- audioManager.setVolume(initialVolume, audioSinkFake.getId());
+ audioManager.setVolume(initialVolume, audioSink.getId());
- String sinkMockId = audioSinkFake.getId();
+ String sinkMockId = audioSink.getId();
return audioManager.getVolume(sinkMockId);
}
@@ -293,14 +287,14 @@ private void assertAddedParameterOption(String param, Locale locale) {
switch (param) {
case AudioManagerImpl.CONFIG_DEFAULT_SINK:
- registerSink();
- id = audioSinkFake.getId();
- label = audioSinkFake.getLabel(locale);
+ audioManager.addAudioSink(audioSink);
+ id = audioSink.getId();
+ label = audioSink.getLabel(locale);
break;
case AudioManagerImpl.CONFIG_DEFAULT_SOURCE:
- registerSource();
- id = audioSourceMock.getId();
- label = audioSourceMock.getLabel(locale);
+ audioManager.addAudioSource(audioSource);
+ id = audioSource.getId();
+ label = audioSource.getLabel(locale);
break;
default:
fail("The parameter must be either default sink or default source");
@@ -309,48 +303,23 @@ private void assertAddedParameterOption(String param, Locale locale) {
Collection parameterOptions = audioManager
.getParameterOptions(URI.create(AudioManagerImpl.CONFIG_URI), param, locale);
+ @SuppressWarnings("null")
BiFunction isParameterOptionAdded = (v, l) -> parameterOptions.stream()
.anyMatch(po -> po.getValue().equals(v) && po.getLabel().equals(l));
assertThat(param + " was not added to the parameter options", isParameterOptionAdded.apply(id, label),
- is(equalTo(true)));
+ is(true));
}
- private void assertServedStream(Integer timeInterval) throws AudioException {
- initializeAudioServlet();
+ private ByteArrayAudioStream getByteArrayAudioStream(String container, String codec) {
+ int bitDepth = 16;
+ int bitRate = 1000;
+ long frequency = 16384;
+ byte[] testByteArray = new byte[] { 0, 1, 2 };
- String path;
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_PCM_SIGNED);
- if (timeInterval != null) {
- path = audioServlet.serve((FixedLengthAudioStream) audioStream, timeInterval);
- } else {
- path = audioServlet.serve(audioStream);
- }
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
+ AudioFormat audioFormat = new AudioFormat(container, codec, true, bitDepth, bitRate, frequency);
- audioManager.stream(url, audioSinkFake.getId());
-
- if (audioManager.getSink() == audioSinkFake) {
- assertThat("The streamed url was not as expected", ((URLAudioStream) audioSinkFake.audioStream).getURL(),
- is(url));
- } else {
- assertThat(String.format("The sink %s received an unexpected stream", audioSinkFake.getId()),
- audioSinkFake.audioStream, is(nullValue()));
- }
+ return new ByteArrayAudioStream(testByteArray, audioFormat);
}
- private enum PlayType {
- STREAM("stream"),
- FILE("file");
-
- private String playType;
-
- PlayType(String playType) {
- this.playType = playType;
- }
-
- public String getPlayType() {
- return playType;
- }
- }
}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioOSGiTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioOSGiTest.java
deleted file mode 100644
index 41636b469cf..00000000000
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioOSGiTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.eclipse.smarthome.core.audio.internal;
-
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Locale;
-import java.util.Set;
-
-import org.eclipse.smarthome.config.core.ConfigConstants;
-import org.eclipse.smarthome.core.audio.AudioException;
-import org.eclipse.smarthome.core.audio.AudioFormat;
-import org.eclipse.smarthome.core.audio.AudioHTTPServer;
-import org.eclipse.smarthome.core.audio.AudioManager;
-import org.eclipse.smarthome.core.audio.AudioSink;
-import org.eclipse.smarthome.core.audio.AudioSource;
-import org.eclipse.smarthome.core.audio.AudioStream;
-import org.eclipse.smarthome.core.audio.ByteArrayAudioStream;
-import org.eclipse.smarthome.core.audio.FileAudioStream;
-import org.eclipse.smarthome.core.audio.internal.fake.AudioSinkFake;
-import org.eclipse.smarthome.test.java.JavaOSGiTest;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-
-/**
- * The base class for the OSGi tests for org.eclipse.smarthome.core.audio.
- *
- * This class is extended by the classes that test {@link AudioManagerImpl}, {@link AudioServlet},
- * {@link AudioConsoleCommandExtension} and {@link AudioFormat}.
- *
- * @author Petar Valchev - Initial contribution
- * @author Wouter Born - Migrate tests from Groovy to Java
- */
-public class AudioOSGiTest extends JavaOSGiTest {
- protected AudioManagerImpl audioManager;
- protected AudioSinkFake audioSinkFake;
- protected AudioStream audioStream;
- protected AudioServlet audioServlet;
-
- protected AudioSource audioSourceMock;
-
- protected final String AUDIO_SERVLET_PROTOCOL = "http";
- protected final String AUDIO_SERVLET_HOSTNAME = "localhost";
- protected final int AUDIO_SERVLET_PORT = 9090;
-
- protected byte[] testByteArray = new byte[] { 0, 1, 2 };
-
- private static String defaultConfigDir;
-
- private static final String CONFIGURATION_DIRECTORY_NAME = "configuration";
-
- protected static final String MP3_FILE_NAME = "mp3AudioFile.mp3";
- protected static final String MP3_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + MP3_FILE_NAME;
-
- protected static final String WAV_FILE_NAME = "wavAudioFile.wav";
- protected static final String WAV_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + WAV_FILE_NAME;
-
- @BeforeClass
- public static void setUpClass() {
- // Store the initial value for the configuration directory property, so that it can be restored at the test end.
- defaultConfigDir = System.getProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT);
- // Set new configuration directory for test purposes.
- System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, CONFIGURATION_DIRECTORY_NAME);
- }
-
- @Before
- public void setUp() {
- audioManager = getService(AudioManager.class, AudioManagerImpl.class);
- }
-
- @After
- public void tearDown() throws IOException {
- if (audioStream != null) {
- audioStream.close();
- }
- }
-
- @AfterClass
- public static void tearDownClass() {
- if (defaultConfigDir != null) {
- // Set the value for the configuration directory property to its initial one.
- System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, defaultConfigDir);
- } else {
- System.clearProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT);
- }
- }
-
- protected void registerSource() {
- audioSourceMock = new AudioSource() {
-
- @Override
- public Set getSupportedFormats() {
- return Collections.emptySet();
- }
-
- @Override
- public String getLabel(Locale locale) {
- return "testSourceLabel";
- }
-
- @Override
- public AudioStream getInputStream(AudioFormat format) throws AudioException {
- return null;
- }
-
- @Override
- public String getId() {
- return "testSourceId";
- }
- };
-
- registerService(audioSourceMock, AudioSource.class.getName());
- }
-
- protected void registerSink() {
- audioSinkFake = new AudioSinkFake();
- registerService(audioSinkFake, AudioSink.class.getName());
- }
-
- protected ByteArrayAudioStream getByteArrayAudioStream(String container, String codec) {
- int bitDepth = 16;
- int bitRate = 1000;
- long frequency = 16384;
-
- AudioFormat audioFormat = new AudioFormat(container, codec, true, bitDepth, bitRate, frequency);
-
- return new ByteArrayAudioStream(testByteArray, audioFormat);
- }
-
- protected FileAudioStream getFileAudioStream(String path) throws AudioException {
- File audioFile = new File(path);
- assertThat(String.format("The file %s does not exist", audioFile.getName()), audioFile.exists(), is(true));
- return new FileAudioStream(audioFile);
- }
-
- protected void assertCompatibleFormat() {
- AudioFormat expectedAudioFormat = audioStream.getFormat();
- AudioFormat sinkAudioFormat = audioSinkFake.audioFormat;
-
- waitForAssert(
- () -> assertThat(
- String.format("The sink %s was not updated with the expected audioFormat %s",
- audioSinkFake.getId(), expectedAudioFormat),
- sinkAudioFormat.isCompatible(expectedAudioFormat), is(true)));
- }
-
- protected void initializeAudioServlet() {
- waitForAssert(() -> {
- audioServlet = getService(AudioHTTPServer.class, AudioServlet.class);
- assertThat("Could not find AudioServlet", audioServlet, is(notNullValue()));
- });
- }
-
- protected String generateURL(String protocol, String hostname, int port, String path) {
- return String.format("%s://%s:%s%s", protocol, hostname, port, path);
- }
-}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioServletTest.java b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioServletTest.java
index b1c6c5ca82b..d6bb739f4bb 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioServletTest.java
+++ b/bundles/core/org.eclipse.smarthome.core.audio.test/src/test/java/org/eclipse/smarthome/core/audio/internal/AudioServletTest.java
@@ -13,36 +13,54 @@
package org.eclipse.smarthome.core.audio.internal;
import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertThat;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
+import java.io.File;
-import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.smarthome.core.audio.AudioException;
+import org.eclipse.smarthome.config.core.ConfigConstants;
import org.eclipse.smarthome.core.audio.AudioFormat;
import org.eclipse.smarthome.core.audio.AudioStream;
-import org.eclipse.smarthome.core.audio.FixedLengthAudioStream;
+import org.eclipse.smarthome.core.audio.FileAudioStream;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
/**
- * OSGi test for {@link AudioServlet}
+ * Test cases for {@link AudioServlet}
*
* @author Petar Valchev - Initial contribution
* @author Wouter Born - Migrate tests from Groovy to Java
*/
-public class AudioServletTest extends AudioOSGiTest {
+public class AudioServletTest extends AbstractAudioServeltTest {
+
private final String MEDIA_TYPE_AUDIO_WAV = "audio/wav";
private final String MEDIA_TYPE_AUDIO_OGG = "audio/ogg";
private final String MEDIA_TYPE_AUDIO_MPEG = "audio/mpeg";
+ private static final String CONFIGURATION_DIRECTORY_NAME = "configuration";
+
+ private static final String WAV_FILE_NAME = "wavAudioFile.wav";
+ private static final String WAV_FILE_PATH = CONFIGURATION_DIRECTORY_NAME + "/sounds/" + WAV_FILE_NAME;
+
+ private final byte[] testByteArray = new byte[] { 0, 1, 2 };
+
+ @Before
+ public void setup() {
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, CONFIGURATION_DIRECTORY_NAME);
+ }
+
+ @After
+ public void tearDown() {
+ System.setProperty(ConfigConstants.CONFIG_DIR_PROG_ARGUMENT, ConfigConstants.DEFAULT_CONFIG_FOLDER);
+ }
+
@Test
- public void audioServletProcessesByteArrayStream() {
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3);
+ public void audioServletProcessesByteArrayStream() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_NONE,
+ AudioFormat.CODEC_MP3);
ContentResponse response = getHttpResponse(audioStream);
@@ -53,8 +71,8 @@ public void audioServletProcessesByteArrayStream() {
}
@Test
- public void audioServletProcessesStreamFromWavFile() throws AudioException {
- audioStream = getFileAudioStream(WAV_FILE_PATH);
+ public void audioServletProcessesStreamFromWavFile() throws Exception {
+ AudioStream audioStream = new FileAudioStream(new File(WAV_FILE_PATH));
ContentResponse response = getHttpResponse(audioStream);
@@ -63,8 +81,9 @@ public void audioServletProcessesStreamFromWavFile() throws AudioException {
}
@Test
- public void audioServletProcessesStreamFromOggContainer() {
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_OGG, AudioFormat.CODEC_PCM_SIGNED);
+ public void audioServletProcessesStreamFromOggContainer() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_OGG,
+ AudioFormat.CODEC_PCM_SIGNED);
ContentResponse response = getHttpResponse(audioStream);
@@ -74,8 +93,9 @@ public void audioServletProcessesStreamFromOggContainer() {
}
@Test
- public void mimeTypeIsNullWhenNoContainerAndTheAudioFormatIsNotMp3() {
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_PCM_SIGNED);
+ public void mimeTypeIsNullWhenNoContainerAndTheAudioFormatIsNotMp3() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_NONE,
+ AudioFormat.CODEC_PCM_SIGNED);
ContentResponse response = getHttpResponse(audioStream);
@@ -84,14 +104,11 @@ public void mimeTypeIsNullWhenNoContainerAndTheAudioFormatIsNotMp3() {
}
@Test
- public void onlyOneRequestToOneTimeStreamsCanBeMade()
- throws InterruptedException, TimeoutException, ExecutionException {
- initializeAudioServlet();
+ public void onlyOneRequestToOneTimeStreamsCanBeMade() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_NONE,
+ AudioFormat.CODEC_MP3);
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3);
-
- String path = audioServlet.serve(audioStream);
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
+ String url = serveStream(audioStream);
Request request = getHttpRequest(url);
@@ -107,15 +124,12 @@ public void onlyOneRequestToOneTimeStreamsCanBeMade()
}
@Test
- public void requestToMultitimeStreamCannotBeDoneAfterTheTimeoutOfTheStreamHasExipred()
- throws InterruptedException, TimeoutException, ExecutionException {
- initializeAudioServlet();
-
- audioStream = getByteArrayAudioStream(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3);
+ public void requestToMultitimeStreamCannotBeDoneAfterTheTimeoutOfTheStreamHasExipred() throws Exception {
+ AudioStream audioStream = getByteArrayAudioStream(testByteArray, AudioFormat.CONTAINER_NONE,
+ AudioFormat.CODEC_MP3);
int streamTimeout = 1;
- String path = audioServlet.serve((FixedLengthAudioStream) audioStream, streamTimeout);
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
+ String url = serveStream(audioStream, streamTimeout);
Request request = getHttpRequest(url);
@@ -131,41 +145,15 @@ public void requestToMultitimeStreamCannotBeDoneAfterTheTimeoutOfTheStreamHasExi
waitForAssert(() -> {
try {
request.send();
- assertThat("The audio stream was not removed from multitime streams",
- audioServlet.getMultiTimeStreams().containsValue(audioStream), is(false));
- } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ } catch (Exception e) {
throw new IllegalStateException(e);
}
+ assertThat("The audio stream was not removed from multitime streams",
+ audioServlet.getMultiTimeStreams().containsValue(audioStream), is(false));
});
response = request.send();
assertThat("The response status was not as expected", response.getStatus(), is(HttpStatus.NOT_FOUND_404));
}
- private ContentResponse getHttpResponse(AudioStream audioStream) {
- initializeAudioServlet();
- String path = audioServlet.serve(audioStream);
- String url = generateURL(AUDIO_SERVLET_PROTOCOL, AUDIO_SERVLET_HOSTNAME, AUDIO_SERVLET_PORT, path);
- try {
- return getHttpRequest(url).send();
- } catch (InterruptedException | TimeoutException | ExecutionException e) {
- throw new IllegalStateException("Failed to HTTP response for audio stream ", e);
- }
- }
-
- private void startHttpClient(HttpClient client) {
- if (!client.isStarted()) {
- try {
- client.start();
- } catch (Exception e) {
- fail("An exception " + e + " was thrown, while starting the HTTP client");
- }
- }
- }
-
- private Request getHttpRequest(String url) {
- HttpClient httpClient = new HttpClient();
- startHttpClient(httpClient);
- return httpClient.newRequest(url).method(HttpMethod.GET);
- }
}
diff --git a/bundles/core/org.eclipse.smarthome.core.audio/src/main/java/org/eclipse/smarthome/core/audio/FileAudioStream.java b/bundles/core/org.eclipse.smarthome.core.audio/src/main/java/org/eclipse/smarthome/core/audio/FileAudioStream.java
index 14e9273ecff..d7d8c520e5e 100644
--- a/bundles/core/org.eclipse.smarthome.core.audio/src/main/java/org/eclipse/smarthome/core/audio/FileAudioStream.java
+++ b/bundles/core/org.eclipse.smarthome.core.audio/src/main/java/org/eclipse/smarthome/core/audio/FileAudioStream.java
@@ -36,10 +36,10 @@ public class FileAudioStream extends FixedLengthAudioStream {
public static final String OGG_EXTENSION = "ogg";
public static final String AAC_EXTENSION = "aac";
- private File file;
- private AudioFormat audioFormat;
+ private final File file;
+ private final AudioFormat audioFormat;
private InputStream inputStream;
- private long length;
+ private final long length;
public FileAudioStream(File file) throws AudioException {
this(file, getAudioFormat(file));
@@ -74,7 +74,7 @@ private static InputStream getInputStream(File file) throws AudioException {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
- throw new AudioException("File '" + file.getName() + "' not found!");
+ throw new AudioException("File '" + file.getAbsolutePath() + "' not found!");
}
}
diff --git a/bundles/test/org.eclipse.smarthome.test/META-INF/MANIFEST.MF b/bundles/test/org.eclipse.smarthome.test/META-INF/MANIFEST.MF
index 945407caa85..c6c62f36d5c 100644
--- a/bundles/test/org.eclipse.smarthome.test/META-INF/MANIFEST.MF
+++ b/bundles/test/org.eclipse.smarthome.test/META-INF/MANIFEST.MF
@@ -12,8 +12,16 @@ Export-Package:
org.eclipse.smarthome.test;uses:="org.osgi.framework"
Import-Package: com.google.common.collect,
groovy.lang,
+ javax.servlet,
+ javax.servlet.http,
org.apache.commons.io,
org.eclipse.jdt.annotation;resolution:=optional,
+ org.eclipse.jetty.http;version="[9.3.15,9.4.0)",
+ org.eclipse.jetty.io;version="[9.3.15,9.4.0)",
+ org.eclipse.jetty.util.component;version="[9.3.15,9.4.0)",
+ org.eclipse.jetty.server;version="[9.3.15,9.4.0)",
+ org.eclipse.jetty.server.handler;version="[9.3.15,9.4.0)",
+ org.eclipse.jetty.servlet;version="[9.3.15,9.4.0)",
org.eclipse.smarthome.config.xml.osgi,
org.eclipse.smarthome.core.i18n;resolution:=optional,
org.eclipse.smarthome.core.service,
diff --git a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/TestServer.java b/bundles/test/org.eclipse.smarthome.test/src/main/java/org/eclipse/smarthome/test/TestServer.java
similarity index 60%
rename from extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/TestServer.java
rename to bundles/test/org.eclipse.smarthome.test/src/main/java/org/eclipse/smarthome/test/TestServer.java
index 649999d19b7..159514863f7 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/TestServer.java
+++ b/bundles/test/org.eclipse.smarthome.test/src/main/java/org/eclipse/smarthome/test/TestServer.java
@@ -10,7 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.smarthome.binding.fsinternetradio.test;
+package org.eclipse.smarthome.test;
+
+import java.util.concurrent.CompletableFuture;
+
+import javax.servlet.Servlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -23,17 +27,27 @@
* Embedded jetty server used in the tests.
*
* @author Velin Yordanov - initial contribution
+ * @author Henning Treu - provide in base test bundle
*
*/
public class TestServer {
private final Logger logger = LoggerFactory.getLogger(TestServer.class);
private Server server;
- private String host;
- private int port;
- private int timeout;
- private ServletHolder servletHolder;
+ private final String host;
+ private final int port;
+ private final int timeout;
+ private final ServletHolder servletHolder;
+ /**
+ * Creates a new {@link TestServer}. The server is started by {@link #startServer()} and stopped by
+ * {@link #stopServer()}, preferably in the tests setup & tearDown methods.
+ *
+ * @param host the host this server runs on.
+ * @param port the port this server runs on. Use {@link TestPortUtil} to find a random free port.
+ * @param timeout the idle timeout when receiving new messages on a connection in milliseconds.
+ * @param servletHolder a {@link ServletHolder} which holds the {@link Servlet} content will be served from.
+ */
public TestServer(String host, int port, int timeout, ServletHolder servletHolder) {
this.host = host;
this.port = port;
@@ -41,7 +55,15 @@ public TestServer(String host, int port, int timeout, ServletHolder servletHolde
this.servletHolder = servletHolder;
}
- public void startServer() {
+ /**
+ * Starts the server and returns a {@link CompletableFuture}. The {@link CompletableFuture} gets completed as soon
+ * as the server is ready to accept connections.
+ *
+ * @return a {@link CompletableFuture} which completes as soon as the server is ready to accept connections.
+ */
+ public CompletableFuture startServer() {
+ final CompletableFuture serverStarted = new CompletableFuture<>();
+
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
@@ -60,20 +82,29 @@ public void run() {
try {
server.start();
+ serverStarted.complete(true);
server.join();
} catch (InterruptedException ex) {
logger.error("Server got interrupted", ex);
+ serverStarted.completeExceptionally(ex);
return;
} catch (Exception e) {
logger.error("Error in starting the server", e);
+ serverStarted.completeExceptionally(e);
return;
}
+
}
});
thread.start();
+
+ return serverStarted;
}
+ /**
+ * Stops the server.
+ */
public void stopServer() {
try {
server.stop();
diff --git a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/org.eclipse.smarthome.binding.fsinternetradio.test.launch b/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/org.eclipse.smarthome.binding.fsinternetradio.test.launch
index 6b0016a0892..2cd0126ec41 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/org.eclipse.smarthome.binding.fsinternetradio.test.launch
+++ b/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/org.eclipse.smarthome.binding.fsinternetradio.test.launch
@@ -162,9 +162,9 @@
-
+
-
+
diff --git a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/FSInternetRadioHandlerJavaTest.java b/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/FSInternetRadioHandlerJavaTest.java
index 0f6d4ad5b9c..d95bfa8a86e 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/FSInternetRadioHandlerJavaTest.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.fsinternetradio.test/src/test/java/org/eclipse/smarthome/binding/fsinternetradio/test/FSInternetRadioHandlerJavaTest.java
@@ -56,6 +56,7 @@
import org.eclipse.smarthome.core.thing.binding.builder.ThingStatusInfoBuilder;
import org.eclipse.smarthome.core.types.UnDefType;
import org.eclipse.smarthome.test.TestPortUtil;
+import org.eclipse.smarthome.test.TestServer;
import org.eclipse.smarthome.test.java.JavaTest;
import org.junit.AfterClass;
import org.junit.Assert;
diff --git a/extensions/binding/org.eclipse.smarthome.binding.homematic.test/org.eclipse.smarthome.binding.homematic.test.launch b/extensions/binding/org.eclipse.smarthome.binding.homematic.test/org.eclipse.smarthome.binding.homematic.test.launch
index 8c84742cdb9..e5fa7a32764 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.homematic.test/org.eclipse.smarthome.binding.homematic.test.launch
+++ b/extensions/binding/org.eclipse.smarthome.binding.homematic.test/org.eclipse.smarthome.binding.homematic.test.launch
@@ -33,7 +33,7 @@
-
+