Brian Stansberry [
http://community.jboss.org/people/brian.stansberry] modified the
document:
"Writing a AS7 Test Case in testsuite module"
To view the document, visit:
http://community.jboss.org/docs/DOC-16664
--------------------------------------------------------------
**
#Background Background
**
#Requirements Requirements
**
#Choices_of_Technologies Choices of Technologies
**
#Test_Case Test Case
**
#Web_Deployment Web Deployment
**
#Where_should_I_look_for_the_source_code Where should I look for the source code?
**
#Show_me_the_test_in_action_buddy Show me the test in action, buddy
**
#Troubleshooting Troubleshooting
h2. Background
h2.
I wanted to write a test case for web security using FORM authentication in the AS7
testsuite. I chose the testsuite/integration submodule.
h2.
h2. Requirements
* I wanted to be able to run the test case in Eclipse.
* I wanted to use JPDA to set breakpoints in the AS7 codebase.
h2.
h2. Choices of Technologies
* Arquilian
* Shrinkwrap
* JUnit
* Eclipse
*Note*: Both Arquilian and Shrinkwrap are available in the AS7 development environment by
default.
h2.
h2. Test Case
/*
* JBoss, Home of Professional Open Source.
* Copyright (c) 2011, Red Hat, Inc., and individual contributors
<snip> Copyright header
*/
package org.jboss.as.testsuite.integration.websecurity;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.api.Run;
import org.jboss.arquillian.api.RunModeType;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Unit Test web security
*
* @author Anil Saldhana
*/
@RunWith(Arquillian.class)
@Run(RunModeType.AS_CLIENT)
public class WebSecurityFORMTestCase {
private static final String URL =
"http://localhost:8080/web-secure/secured/";
@Deployment
public static WebArchive deployment() {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
URL webxml = tccl.getResource("web-secure.war/web.xml");
WebArchive war = ShrinkWrap.create(WebArchive.class, "web-secure.war");
war.addClass(SecuredServlet.class);
URL userProp = tccl.getResource("web-secure.war/users.properties");
URL roleProp = tccl.getResource("web-secure.war/roles.properties");
URL loginJSP = tccl.getResource("web-secure.war/login.jsp");
URL errorJSP = tccl.getResource("web-secure.war/error.jsp");
war.addResource(loginJSP, "login.jsp");
war.addResource(errorJSP, "error.jsp");
war.addResource(userProp, "/WEB-INF/classes/users.properties");
war.addResource(roleProp, "/WEB-INF/classes/roles.properties");
war.setWebXML(webxml);
return war;
}
/**
* Test with user "anil" who has the right password and the right role to
access the servlet
*
* @throws Exception
*/
@Test
public void testSuccessfulAuth() throws Exception {
makeCall("anil", "anil", 200);
}
/**
* <p>
* Test with user "marcus" who has the right password but does not have the
right role
* </p>
* <p>
* Should be a HTTP/403
* </p>
*
* @throws Exception
*/
@Test
public void testUnsuccessfulAuth() throws Exception {
makeCall("marcus", "marcus", 403);
}
protected void makeCall(String user, String pass, int expectedStatusCode) throws
Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
HttpGet httpget = new HttpGet(URL);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null)
entity.consumeContent();
// We should get the Login Page
StatusLine statusLine = response.getStatusLine();
System.out.println("Login form get: " + statusLine);
assertEquals(200, statusLine.getStatusCode());
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
// We should now login with the user name and password
HttpPost httpost = new HttpPost(URL + "/j_security_check");
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("j_username", user));
nvps.add(new BasicNameValuePair("j_password", pass));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httpost);
entity = response.getEntity();
if (entity != null)
entity.consumeContent();
statusLine = response.getStatusLine();
// Post authentication - we have a 302
assertEquals(302, statusLine.getStatusCode());
Header locationHeader = response.getFirstHeader("Location");
String location = locationHeader.getValue();
HttpGet httpGet = new HttpGet(location);
response = httpclient.execute(httpGet);
entity = response.getEntity();
if (entity != null)
entity.consumeContent();
System.out.println("Post logon cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
// Either the authentication passed or failed based on the expected status
code
statusLine = response.getStatusLine();
assertEquals(expectedStatusCode, statusLine.getStatusCode());
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
}
In this test case, I am specifying that the test case should run using Arquilian (via
@RunWith) annotation. Plus I am telling Arquilian to run the test as a client test case
and not inside AS7. [via @Run(RunModeType.AS_CLIENT) ] +If you want the test to run
inside AS7, then you have to use IN_CONTAINER (which is default anyway).+
Also note above. that I am adding users.properties and roles.properties to WEB-INF/classes
directory inside the Web Archive.+
+
h2. Web Deployment
h2.
I need the following Items in my web archive
* Servlet
* web.xml
* Two properties files (users.properties and roles.properties)
Let us look at the servlet
/*
* JBoss, Home of Professional Open Source.
* Copyright (c) 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
* <SNIP>
*/
package org.jboss.as.testsuite.integration.websecurity;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A simple servlet that just writes back a string
*
* @author Anil Saldhana
*/
@WebServlet(urlPatterns = { "/secured/" })
@ServletSecurity(@HttpConstraint(rolesAllowed = { "gooduser" }))
public class SecuredServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
Writer writer = resp.getWriter();
writer.write("GOOD");
}
}
My test resources were in a folder as
web-secure.war/
login.jsp
error.jsp
users.properties
roles.properties
web.xml
h2.
h2. Where should I look for the source code?
https://github.com/anilsaldhana/jboss-as/commit/0efdc673a45d6d17255918324...
https://github.com/anilsaldhana/jboss-as/commit/0efdc673a45d6d17255918324...
https://github.com/anilsaldhana/jboss-as/commit/0efdc673a45d6d17255918324...
h2.
h2.
h2. Show me the test in action, buddy
anil@localhost:~/as7/jboss-as/testsuite/integration$ mvn clean install
Running org.jboss.as.testsuite.integration.websecurity.WebSecurityFORMTestCase
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.531 sec
h2.
h2. Troubleshooting
* How do I run AS7 with JPDA enabled?
** Uncomment the following line in bin/standalone.conf
** #JAVA_OPTS="$JAVA_OPTS
-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"
* Any Eclipse settings for the test case?* VM arguments in the eclipse config for the test
case was
*
-Djboss.home=/home/anil/as7/jboss-as/testsuite/integration/../../build/target/jboss-7.0.0.Beta2
* How do I see what is in the web archive ShrinkWrap creates? You definitely need to add
this always.* System.out.println(war.toString(true));
* What about when Arquilian is running in a managed mode?* Stuart Douglas gave some
insight into this.
* There are two ways, you can either start a standalone instance and attach your
debugger to it normally,
and then run
mvn install -Premote -Dtest=com.my.Test
Alternatively
mvn install -Djboss.options="-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787"
And then attach. This way will not let you use -Dtest= though,
so generally when I am debugging I use the remote profile.
--------------------------------------------------------------
Comment by going to Community
[
http://community.jboss.org/docs/DOC-16664]
Create a new document in JBoss AS7 Development at Community
[
http://community.jboss.org/choose-container!input.jspa?contentType=102&am...]