package org.jboss.as.test.integration.deployment.structure.war.symbolicLink;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import org.junit.Assert;
import org.junit.Assume;
import org.apache.commons.lang.SystemUtils;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.as.test.shared.TestSuiteEnvironment;
import org.jboss.dmr.ModelNode;
import org.jboss.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Unit test to make sure that the symbolic linking feature on the web subsystem is enabled properly.
* Corresponding JIRA: AS7-3414.
*
* @author navssurtani
*/
@RunWith(Arquillian.class)
@RunAsClient
public class SymlinkingUnitTestCase {
private static final Logger logger = Logger.getLogger(SymlinkingUnitTestCase.class);
private static final String WAR_NAME = "explodedDeployment.war";
private static File warDeployment = null;
private static File symbolic = null;
private static ModelControllerClient controllerClient = TestSuiteEnvironment.getModelControllerClient();
@BeforeClass
public static void beforeClass() throws IOException, InterruptedException {
Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS);
logger.infof("beforeClass() call.");
// We are going to check whether or not the war deployment actually exists.
Assert.assertTrue(checkForDeployment());
// Now create the symlink.
createSymlink();
}
@AfterClass
public static void afterClass() throws IOException {
if (SystemUtils.IS_OS_WINDOWS) {
// skip windows;
} else {
logger.infof("afterClass() call.");
// Delete the symlink
symbolic.delete();
controllerClient.close();
controllerClient = null;
}
}
@After
public void tearDown() throws IOException {
logger.infof("In the tearDown() call.");
ModelNode removeSystemProperty = Util.createRemoveOperation(PathAddress.pathAddress(systemPropertyAddress()));
// Define the content.
ModelNode content = new ModelNode();
content.get(0).get(ModelDescriptionConstants.ARCHIVE).set(false);
content.get(0).get(ModelDescriptionConstants.PATH).set(warDeployment.getAbsolutePath());
// Undeploy operation.
ModelNode undeployOperation = Util.getEmptyOperation(ModelDescriptionConstants.UNDEPLOY, new ModelNode().add(ModelDescriptionConstants.DEPLOYMENT, WAR_NAME));
undeployOperation.get(ModelDescriptionConstants.CONTENT).set(ModelDescriptionConstants.CONTENT);
undeployOperation.get(ModelDescriptionConstants.ENABLE).set(true);
// Remove operation.
ModelNode removeOperation = Util.getEmptyOperation(ModelDescriptionConstants.REMOVE, new ModelNode().add(ModelDescriptionConstants.DEPLOYMENT, WAR_NAME));
removeOperation.get(ModelDescriptionConstants.CONTENT).set(ModelDescriptionConstants.CONTENT);
removeOperation.get(ModelDescriptionConstants.ENABLE).set(true);
// Composite operation.
ModelNode compositeOperation = Util.getEmptyOperation(ModelDescriptionConstants.COMPOSITE, new ModelNode());
ModelNode steps = compositeOperation.get(ModelDescriptionConstants.STEPS);
steps.add(undeployOperation);
steps.add(removeOperation);
steps.add(removeSystemProperty);
//logger.infof("Composite operation: %s", compositeOperation.toString());
ModelNode compositeResult = controllerClient.execute(compositeOperation);
Assert.assertEquals(ModelDescriptionConstants.SUCCESS, compositeResult.get(ModelDescriptionConstants.OUTCOME).asString());
}
@Test
public void testEnabled() throws IOException {
//logger.infof("Testing enabled bit");
// By default we should not be able to browse to the symlinked page.
Assert.assertTrue(getURLcode("symbolic") == 404);
setup(true);
// First make sure that we can browse to index.html. This should work in the enabled or disabled version.
Assert.assertTrue(getURLcode("index") == 200);
// Now with symbolic.html.
Assert.assertTrue(getURLcode("symbolic") == 200);
}
@Test
public void testDisabled() throws IOException {
logger.infof("Testing disabled bit.");
// By default we should not be able to browse to the symlinked page.
Assert.assertTrue(getURLcode("symbolic") == 404);
setup(false);
// First make sure that we can browse to index.html. This should work in the enabled or disabled version.
Assert.assertTrue(getURLcode("index") == 200);
// Now with symbolic.html.
Assert.assertTrue(getURLcode("symbolic") == 404);
}
private void setup(boolean symlinkingEnabled) throws IOException {
logger.infof("Entered the setup call within %s & the boolean parameter is %s",
this.getClass().getName(), symlinkingEnabled);
ModelNode addSysProperty = Util.createAddOperation(PathAddress.pathAddress(systemPropertyAddress()));
addSysProperty.get(ModelDescriptionConstants.VALUE).set(Boolean.toString(symlinkingEnabled));
ModelNode result = controllerClient.execute(addSysProperty);
Assert.assertEquals(ModelDescriptionConstants.SUCCESS, result.get(ModelDescriptionConstants.OUTCOME).asString());
// Define the content.
ModelNode content = new ModelNode();
content.get(0).get(ModelDescriptionConstants.ARCHIVE).set(false);
content.get(0).get(ModelDescriptionConstants.PATH).set(warDeployment.getAbsolutePath());
// Add operation.
ModelNode addOperation = Util.getEmptyOperation(ModelDescriptionConstants.ADD, new ModelNode().add(ModelDescriptionConstants.DEPLOYMENT, WAR_NAME));
addOperation.get(ModelDescriptionConstants.CONTENT).set(content);
addOperation.get(ModelDescriptionConstants.ENABLE).set(true);
result = controllerClient.execute(addOperation);
Assert.assertEquals(ModelDescriptionConstants.SUCCESS, result.get(ModelDescriptionConstants.OUTCOME).asString());
// Deployment operation.
ModelNode deploymentOperation = Util.getEmptyOperation(ModelDescriptionConstants.DEPLOY, new ModelNode().add(ModelDescriptionConstants.DEPLOYMENT, WAR_NAME));
deploymentOperation.get(ModelDescriptionConstants.CONTENT).set(content);
deploymentOperation.get(ModelDescriptionConstants.ENABLE).set(true);
result = controllerClient.execute(deploymentOperation);
Assert.assertEquals(ModelDescriptionConstants.SUCCESS, result.get(ModelDescriptionConstants.OUTCOME).asString());
}
private int getURLcode(String htmlPage) {
int code = 0;
try {
String url = "http://" + TestSuiteEnvironment.getServerAddress() + ":8080/explodedDeployment/"
+ htmlPage + ".html";
logger.infof("%s is the built URL.", url);
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
code = urlConnection.getResponseCode();
logger.infof("Received response code of: " + code);
} catch (Exception e) {
logger.infof("Exception of type: %s caught", e.getClass(), e);
}
return code;
}
private ModelNode systemPropertyAddress() {
ModelNode address = new ModelNode();
address.add("system-property", "symbolic-linking-enabled");
address.protect();
return address;
}
private static boolean checkForDeployment() {
String warLocation = getWarLocation();
warDeployment = new File(warLocation);
logger.infof("Checking to see if exploded deployment exists at path: " + warDeployment.getAbsolutePath());
return warDeployment.exists();
}
private static String getWarLocation() {
return SymlinkingUnitTestCase.class.getResource(WAR_NAME).getPath();
}
private static void createSymlink() throws IOException, InterruptedException {
// TODO: navssurtani: once AS7 is on a minimum of Java 7 then we can change the approach used to create the symlink.
File index = new File(warDeployment, "index.html");
logger.infof("Path to index file is: " + index.getAbsolutePath());
Assert.assertTrue(index.exists());
// Now set up the information to create the symlink.
String toExecute;
if (SystemUtils.IS_OS_WINDOWS) {
logger.infof("Windows based OS detected.");
toExecute = "mklink \\D " + index.getAbsolutePath() + " " + warDeployment.getAbsolutePath()
+ "\\symbolic.html";
} else {
logger.infof("UNIX based OS detected.");
toExecute = "ln -s " + index.getAbsolutePath() + " " + warDeployment.getAbsolutePath() + "/symbolic.html";
}
logger.infof("String to be executed is: " + toExecute);
Runtime.getRuntime().exec(toExecute).waitFor();
symbolic = new File(warDeployment.getAbsolutePath(), "symbolic.html");
logger.infof("Absolute path of symbolic file is located at %s. Checking to see if the file really exists.",
symbolic.getAbsolutePath());
Assert.assertTrue(symbolic.exists());
}
}