1   /*
2    * Wallace IMAP Server
3    * Copyright (C) 2004  Robert Newson
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  package net.sf.wallace.mina;
20  
21  import java.util.Properties;
22  import java.util.Random;
23  import java.util.concurrent.ArrayBlockingQueue;
24  import java.util.concurrent.CountDownLatch;
25  import java.util.concurrent.ThreadPoolExecutor;
26  import java.util.concurrent.TimeUnit;
27  
28  import javax.mail.Session;
29  import javax.mail.Store;
30  
31  import junit.framework.Assert;
32  import junit.framework.TestCase;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  import org.springframework.context.ConfigurableApplicationContext;
37  import org.springframework.context.support.ClassPathXmlApplicationContext;
38  
39  /***
40   * Test various types of scalability.
41   * 
42   * @author rnewson
43   */
44  public final class ScalabilityTest extends TestCase {
45  
46      private ConfigurableApplicationContext context;
47  
48      protected Session session;
49  
50      protected Log log = LogFactory.getLog(getClass());
51  
52      protected Random random = new Random();
53  
54      protected void setUp() {
55          context = new ClassPathXmlApplicationContext("applicationContext.xml");
56          final Properties properties = new Properties();
57          session = Session.getInstance(properties);
58      }
59  
60      protected void tearDown() {
61          context.close();
62      }
63  
64      public void testConsecutiveSessions() throws Exception {
65          final int SESSION_COUNT = 1000;
66          int count = SESSION_COUNT;
67  
68          for (int i = 0; i < SESSION_COUNT; i++) {
69              final Store store = session.getStore("imap");
70              store.connect("localhost", 10143, "testuser", "password");
71              store.close();
72              count--;
73          }
74  
75          Assert.assertEquals("Not all sessions completed.", 0, count);
76      }
77  
78      public void testConcurrentSessions() throws Exception {
79          final int SESSION_COUNT = 300;
80  
81          final CountDownLatch latch = new CountDownLatch(SESSION_COUNT);
82  
83          final Runnable runnable = new Runnable() {
84  
85              public void run() {
86                  try {
87                      final Store store = session.getStore("imap");
88                      store.connect("localhost", 10143, "testuser", "password");
89                      Thread.sleep(random.nextInt(3 * 1000));
90                      store.close();
91                      latch.countDown();
92                  } catch (Exception e) {
93                      // Ignored.
94                  }
95              }
96          };
97  
98          final ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 100, 10, TimeUnit.SECONDS,
99                  new ArrayBlockingQueue<Runnable>(SESSION_COUNT));
100 
101         for (int i = 0; i < SESSION_COUNT; i++) {
102             executor.execute(runnable);
103         }
104 
105         if (!latch.await(30, TimeUnit.SECONDS)) {
106             fail("At least " + latch.getCount() + " of " + SESSION_COUNT + " did not complete successfully.");
107         }
108 
109         executor.shutdownNow();
110     }
111 
112 }