Jelajahi Sumber

Some tests used for obtaining performance data.

Luke Taylor 17 tahun lalu
induk
melakukan
c564a879d4

+ 5 - 0
itest/context/pom.xml

@@ -18,5 +18,10 @@
             <version>4.4</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

+ 136 - 0
itest/context/src/test/java/org/springframework/security/performance/FilterChainPerformanceTests.java

@@ -0,0 +1,136 @@
+package org.springframework.security.performance;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.security.Authentication;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.context.HttpSessionSecurityContextRepository;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.security.util.FilterChainProxy;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.StopWatch;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+/**
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ * @since 2.0
+ */
+@ContextConfiguration(locations={"/filter-chain-performance-app-context.xml"})
+@RunWith(SpringJUnit4ClassRunner.class)
+public class FilterChainPerformanceTests {
+    private static final int N_INVOCATIONS = 1000;
+    private static final int N_AUTHORITIES = 200;
+    private static StopWatch sw = new StopWatch("Filter Chain Performance Tests");
+
+    private final UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("bob", "bobspassword", createRoles(N_AUTHORITIES));
+    private HttpSession session;
+
+    @Autowired
+    @Qualifier("fcpMinimalStack")
+    private FilterChainProxy minimalStack;
+
+    @Autowired
+    @Qualifier("fcpFullStack")
+    private FilterChainProxy fullStack;
+
+    @Before
+    public void createAuthenticatedSession() {
+        session = new MockHttpSession();
+        SecurityContextHolder.getContext().setAuthentication(user);
+        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
+        SecurityContextHolder.clearContext();
+    }
+
+    @After
+    public void clearContext() {
+        SecurityContextHolder.clearContext();
+    }
+
+    @AfterClass
+    public static void dumpStopWatch() {
+        System.out.println(sw.prettyPrint());
+    }
+
+    private MockHttpServletRequest createRequest(String url) {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setSession(session);
+        request.setServletPath(url);
+        request.setMethod("GET");
+        return request;
+    }
+
+    private void runWithStack(FilterChainProxy stack) throws Exception {
+        for(int i = 0; i < N_INVOCATIONS; i++) {
+            MockHttpServletRequest request = createRequest("/somefile.html");
+            stack.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
+            session = request.getSession();
+        }
+    }
+
+    @Test
+    public void minimalStackInvocation() throws Exception {
+        sw.start("Run with Minimal Filter Stack");
+        runWithStack(minimalStack);
+        sw.stop();
+    }
+
+    @Test
+    public void fullStackInvocation() throws Exception {
+        sw.start("Run with Full Filter Stack");
+        runWithStack(fullStack);
+        sw.stop();
+    }
+
+    /**
+     * Creates data from 1 to N_AUTHORITIES in steps of 10, performing N_INVOCATIONS for each
+     */
+    @Test
+    public void provideDataOnScalingWithNumberOfAuthoritiesUserHas() throws Exception {
+        StopWatch sw = new StopWatch("Scaling with nAuthorities");
+        for (int user=0; user < N_AUTHORITIES/10; user ++) {
+            int nAuthorities = user == 0 ? 1 : user*10;
+            SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("bob", "bobspassword", createRoles(nAuthorities)));
+            session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
+            SecurityContextHolder.clearContext();
+            sw.start(Integer.toString(nAuthorities) + " authorities");
+            runWithStack(minimalStack);
+            System.out.println(sw.shortSummary());
+            sw.stop();
+        }
+        System.out.println(sw.prettyPrint());
+    }
+
+    private List<GrantedAuthority> createRoles(int howMany) {
+     // This is always the worst case scenario - the required role is ROLE_1, but they are created in reverse order
+        GrantedAuthority[] roles = new GrantedAuthority[howMany];
+
+        for (int i = howMany - 1; i >=0 ; i--) {
+            roles[i] = new GrantedAuthorityImpl("ROLE_" + i);
+        }
+
+        return Arrays.asList(roles);
+    }
+}

+ 105 - 0
itest/context/src/test/resources/filter-chain-performance-app-context.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  -
+  - $Id: applicationContext-security-ns.xml 2396 2007-12-23 16:36:44Z luke_t $
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:sec="http://www.springframework.org/schema/security"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
+
+    <bean id="fcpMinimalStack" class="org.springframework.security.util.FilterChainProxy">
+        <sec:filter-chain-map path-type="ant">
+            <sec:filter-chain pattern="/**" filters="scpf,preAuthFilter,etf,fsi"/>
+        </sec:filter-chain-map>
+    </bean>
+
+    <bean id="fcpFullStack" class="org.springframework.security.util.FilterChainProxy">
+        <sec:filter-chain-map path-type="ant">
+            <sec:filter-chain pattern="/**" filters="scpf,preAuthFilter,apf,basicPf,logoutFilter,scharf,etf,fsi"/>
+        </sec:filter-chain-map>
+    </bean>
+
+    <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
+        <property name="providers">
+            <list>
+               <bean class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
+                   <property name="userDetailsService" ref="userService"/>
+               </bean>
+            </list>
+        </property>
+    </bean>
+
+    <sec:user-service id="userService">
+        <sec:user name="bob" password="bobspassword" authorities="ROLE_0,ROLE_1"/>
+    </sec:user-service>
+
+    <bean id="scpf" class="org.springframework.security.context.SecurityContextPersistenceFilter"/>
+
+    <bean id="apf" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
+        <property name="authenticationManager" ref="authenticationManager"/>
+    </bean>
+
+    <bean id="basicPf" class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
+        <property name="authenticationManager" ref="authenticationManager"/>
+        <property name="ignoreFailure" value="true"/>
+    </bean>
+
+    <bean id="preAuthFilter" class="org.springframework.security.ui.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
+        <property name="authenticationManager" ref="authenticationManager"/>
+    </bean>
+
+    <bean id="scharf" class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />
+
+    <bean id="preAuthenticatedProcessingFilterEntryPoint"
+            class="org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint"/>
+
+    <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
+        <constructor-arg value="/"/>
+        <constructor-arg>
+            <list>
+                <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
+            </list>
+        </constructor-arg>
+    </bean>
+
+    <bean id="etf" class="org.springframework.security.ui.ExceptionTranslationFilter">
+        <property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/>
+    </bean>
+
+
+    <bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
+        <property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
+    </bean>
+
+    <bean id="preAuthenticatedUserDetailsService" class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
+        <property name="userDetailsService" ref="userService"/>
+    </bean>
+
+    <bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
+        <property name="allowIfAllAbstainDecisions" value="false"/>
+        <property name="decisionVoters">
+            <list>
+                <ref bean="roleVoter"/>
+            </list>
+        </property>
+    </bean>
+
+    <bean id="fsi" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
+        <property name="authenticationManager" ref="authenticationManager"/>
+        <property name="accessDecisionManager" ref="accessDecisionManager"/>
+        <property name="objectDefinitionSource">
+            <sec:filter-invocation-definition-source>
+                <sec:intercept-url pattern="/secure/extreme/**" access="ROLE_2"/>
+                <sec:intercept-url pattern="/secure/**" access="ROLE_1"/>
+                <sec:intercept-url pattern="/**" access="ROLE_0"/>
+            </sec:filter-invocation-definition-source>
+        </property>
+    </bean>
+
+    <bean id="roleVoter" class="org.springframework.security.vote.RoleVoter"/>
+
+</beans>

+ 13 - 0
itest/context/src/test/resources/log4j.properties

@@ -0,0 +1,13 @@
+# Logging
+#
+# $Id$
+
+log4j.rootLogger=WARN, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%p,%c{1}] %m%n
+
+log4j.logger.org.springframework.security=WARN
+log4j.logger.org.springframework.ldap=WARN
+log4j.logger.org.apache.directory=ERROR