Skip to content

Commit

Permalink
ARTEMIS-3044 Add Artemis web console tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brusdev authored and clebertsuconic committed Mar 10, 2021
1 parent a9566e7 commit 5a57940
Show file tree
Hide file tree
Showing 13 changed files with 697 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/hacking-guide/en/tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ This class does all the setup of a simple server automatically and provides the
is an example based on `org.apache.activemq.artemis.tests.integration.SimpleTest` but extends `org.apache.activemq.artemis.tests.util.SingleServerTestBase`
which eliminates all the setup and class variables which are provided by `SingleServerTestBase` itself.

## Writing Web Tests

The broker has a web console based on [hawtio](https://github.com/hawtio/hawtio) and the `smoke-tests` are used to test it.
For instance, the [ConsoleTest](https://github.com/apache/activemq-artemis/blob/master/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/ConsoleTest.java)
checks the web console using the [selenium framework](https://github.com/SeleniumHQ/selenium).
The tests can be executed using the local browsers or the [webdriver testcontainers](https://www.testcontainers.org/modules/webdriver_containers).
To use your local Google Chrome browser download the [WebDriver for Chrome](https://chromedriver.chromium.org/) and set
the `webdriver.chrome.driver` property with the WebDriver path, ie `-Dwebdriver.chrome.driver=/home/artemis/chromedriver_linux64/chromedriver`.
To use your local Firefox browser download the [WebDriver for Firefox](https://github.com/mozilla/geckodriver/) and set
the `webdriver.gecko.driver` property with the WebDriver path, ie `-Dwebdriver.gecko.driver=/home/artemis/geckodriver-linux64/geckodriver`.
To use the [webdriver testcontainers](https://www.testcontainers.org/modules/webdriver_containers) install docker.

## Keys for writing good tests

### Use log.debug
Expand Down
28 changes: 28 additions & 0 deletions tests/smoke-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>selenium</artifactId>
<version>1.15.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -140,6 +152,22 @@
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-maven-plugin</artifactId>
<executions>
<execution>
<phase>test-compile</phase>
<id>create-create-console</id>
<goals>
<goal>create</goal>
</goals>
<configuration>
<role>amq</role>
<user>admin</user>
<password>admin</password>
<allowAnonymous>false</allowAnonymous>
<noWeb>false</noWeb>
<instance>${basedir}/target/console</instance>
<configuration>${basedir}/target/classes/servers/console</configuration>
</configuration>
</execution>
<execution>
<phase>test-compile</phase>
<id>create0</id>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

<!-- This policy file controls the Jolokia JMX-HTTP bridge security options for the web console.
see: https://jolokia.org/reference/html/security.html -->
<restrict>

<cors>
<!-- Allow cross origin access from localhost ... -->
<allow-origin>*://localhost*</allow-origin>
<allow-origin>*://host.testcontainers.internal*</allow-origin>


<!-- Options from this point on are auto-generated by Create.java from the Artemis CLI -->
<!-- Check for the proper origin on the server side, too -->
<strict-checking/>
</cors>

</restrict>
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.activemq.artemis.tests.smoke.console;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Function;

import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
import org.apache.activemq.artemis.util.ServerUtil;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.Testcontainers;
import org.testcontainers.containers.BrowserWebDriverContainer;

@RunWith(Parameterized.class)
public abstract class ConsoleTest extends SmokeTestBase {
protected static final String SERVER_NAME = "console";
protected static final String SERVER_ADMIN_USERNAME = "admin";
protected static final String SERVER_ADMIN_PASSWORD = "admin";

protected static final int DEFAULT_TIMEOUT = 10000;
protected static final String DEFAULT_SERVER_URL = "http://localhost:8161";
protected static final String DEFAULT_CONTAINER_SERVER_URL = "http://host.testcontainers.internal:8161";
protected static final String DEFAULT_CONSOLE_BRAND_IMAGE = "/activemq-branding/plugin/img/activemq.png";

protected WebDriver driver;
protected MutableCapabilities browserOptions;
protected String serverUrl = DEFAULT_SERVER_URL;
private BrowserWebDriverContainer browserWebDriverContainer;

@Parameterized.Parameters(name = "browserOptions={0}")
public static Collection getParameters() {
return Arrays.asList(new Object[][]{{new ChromeOptions()}, {new FirefoxOptions()}});
}

public ConsoleTest(MutableCapabilities browserOptions) {
this.browserOptions = browserOptions;
}

@Before
public void before() throws Exception {
cleanupData(SERVER_NAME);
disableCheckThread();
startServer(SERVER_NAME, 0, 0);
ServerUtil.waitForServerToStart(0, SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, 30000);


// The ConsoleTest checks the web console using the selenium framework[1].
// The tests can be executed using the local browsers or the webdriver testcontainers[2].
// To use your local Google Chrome browser download the WebDriver for Chrome[3] and set
// the `webdriver.chrome.driver` property with the WebDriver path, ie
// -Dwebdriver.chrome.driver=/home/developer/chromedriver_linux64/chromedriver
// To use your local Firefox browser download the WebDriver for Firefox[4] and set
// the `webdriver.gecko.driver` property with the WebDriver path, ie
// -Dwebdriver.gecko.driver=/home/developer/geckodriver-v0.28.0-linux64/geckodriver
// To use the webdriver testcontainers[2] install docker.
//
// [1] https://github.com/SeleniumHQ/selenium
// [2] https://www.testcontainers.org/modules/webdriver_containers
// [3] https://chromedriver.chromium.org/
// [4] https://github.com/mozilla/geckodriver/

try {
if (ChromeOptions.class.equals(browserOptions.getClass()) &&
System.getProperty("webdriver.chrome.driver") != null) {
driver = new ChromeDriver((ChromeOptions)browserOptions);
} else if (FirefoxOptions.class.equals(browserOptions.getClass()) &&
System.getProperty("webdriver.gecko.driver") != null) {
driver = new FirefoxDriver((FirefoxOptions)browserOptions);
} else {
serverUrl = DEFAULT_CONTAINER_SERVER_URL;
Testcontainers.exposeHostPorts(8161);
browserWebDriverContainer = new BrowserWebDriverContainer().withCapabilities(this.browserOptions);
browserWebDriverContainer.start();
driver = browserWebDriverContainer.getWebDriver();
}
} catch (Exception e) {
Assume.assumeNoException("Error on loading the web driver", e);
}

// Wait for server console
WebDriverWait loadWebDriverWait = new WebDriverWait(
driver, Duration.ofMillis(30000).getSeconds());

loadWebDriverWait.until((Function<WebDriver, Object>) webDriver -> {
try {
webDriver.get(serverUrl + "/console");
return true;
} catch (Exception ignore) {
return false;
}
});
}

@After
public void stopWebDriver() {
if (browserWebDriverContainer != null) {
browserWebDriverContainer.stop();
} else if (driver != null) {
driver.close();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.activemq.artemis.tests.smoke.console;

import org.apache.activemq.artemis.tests.smoke.console.pages.LoginPage;
import org.apache.activemq.artemis.tests.smoke.console.pages.StatusPage;
import org.junit.Test;
import org.openqa.selenium.MutableCapabilities;

public class LoginTest extends ConsoleTest {

public LoginTest(MutableCapabilities browserOptions) {
super(browserOptions);
}

@Test
public void testLogin() {
LoginPage loginPage = new LoginPage(driver);
StatusPage statusPage = loginPage.loginValidUser(
SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, DEFAULT_TIMEOUT);

assertEquals(SERVER_ADMIN_USERNAME, statusPage.getUser());
}

@Test
public void testLoginBrand() {
String expectedBrandImage = serverUrl + System.getProperty(
"artemis.console.brand.image", DEFAULT_CONSOLE_BRAND_IMAGE);

LoginPage loginPage = new LoginPage(driver);
assertEquals(expectedBrandImage, loginPage.getBrandImage(DEFAULT_TIMEOUT));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.activemq.artemis.tests.smoke.console;

import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.messages.Consumer;
import org.apache.activemq.artemis.cli.commands.messages.Producer;
import org.apache.activemq.artemis.tests.smoke.console.pages.LoginPage;
import org.apache.activemq.artemis.tests.smoke.console.pages.MessagePage;
import org.apache.activemq.artemis.tests.smoke.console.pages.QueuePage;
import org.apache.activemq.artemis.tests.smoke.console.pages.QueuesPage;
import org.apache.activemq.artemis.tests.smoke.console.pages.StatusPage;
import org.apache.activemq.artemis.utils.Wait;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.openqa.selenium.MutableCapabilities;

@RunWith(Parameterized.class)
public class QueuesTest extends ConsoleTest {

public QueuesTest(MutableCapabilities browserOptions) {
super(browserOptions);
}

@Test
public void testDefaultQueues() throws Exception {
LoginPage loginPage = new LoginPage(driver);
StatusPage statusPage = loginPage.loginValidUser(
SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, DEFAULT_TIMEOUT);
QueuesPage queuesPage = statusPage.getQueuesPage(DEFAULT_TIMEOUT);

Wait.assertEquals(1, () -> queuesPage.countQueue("DLQ"));
assertEquals(0, queuesPage.getMessagesCount("DLQ"));

Wait.assertEquals(1, () -> queuesPage.countQueue("ExpiryQueue"));
assertEquals(0, queuesPage.getMessagesCount("ExpiryQueue"));
}

@Test
public void testAutoCreatedQueue() throws Exception {
final int messages = 1;
final String queueName = "TEST";
final String messageText = "TEST";

LoginPage loginPage = new LoginPage(driver);
StatusPage statusPage = loginPage.loginValidUser(
SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, DEFAULT_TIMEOUT);
QueuesPage beforeQueuesPage = statusPage.getQueuesPage(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue("DLQ"));
Wait.assertEquals(0, () -> beforeQueuesPage.countQueue(queueName));

Producer producer = new Producer();
producer.setUser(SERVER_ADMIN_USERNAME);
producer.setPassword(SERVER_ADMIN_PASSWORD);
producer.setDestination(queueName);
producer.setMessageCount(messages);
producer.setMessage(messageText);
producer.setSilentInput(true);
producer.execute(new ActionContext());

beforeQueuesPage.refresh(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue("DLQ"));
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(queueName));
assertEquals(messages, beforeQueuesPage.getMessagesCount(queueName));

QueuePage queuePage = beforeQueuesPage.getQueuePage(queueName, DEFAULT_TIMEOUT);
MessagePage messagePage = queuePage.getMessagePage(0, DEFAULT_TIMEOUT);
assertEquals(messageText, messagePage.getMessageText());

Consumer consumer = new Consumer();
consumer.setUser(SERVER_ADMIN_USERNAME);
consumer.setPassword(SERVER_ADMIN_PASSWORD);
consumer.setDestination(queueName);
consumer.setMessageCount(messages);
consumer.setSilentInput(true);
consumer.setReceiveTimeout(2000);
consumer.setBreakOnNull(true);
int consumed = (int)consumer.execute(new ActionContext());

assertEquals(messages, consumed);

QueuesPage afterQueuesPage = messagePage.getQueuesPage(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> afterQueuesPage.countQueue("DLQ"));
Wait.assertEquals(0, () -> afterQueuesPage.countQueue(queueName));
}
}
Loading

0 comments on commit 5a57940

Please sign in to comment.