1   // 
2   // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   // All rights reserved. 
4   // 
5   // Redistribution and use in source and binary forms, with or without modification,  
6   // are permitted provided that the following conditions are met: 
7   //  
8   // * Redistributions of source code must retain the above copyright notice,  
9   //	 this list of conditions and the following disclaimer. 
10  // * Redistributions in binary form must reproduce the above copyright notice,  
11  //	 this list of conditions and the following disclaimer in the documentation  
12  //	 and/or other materials provided with the distribution. 
13  // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //	 nor the names of its contributors may be used to endorse or promote products  
15  //	 derived from this software without specific prior written permission. 
16  // 
17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  // POSSIBILITY OF SUCH DAMAGE. 
27  // 
28  package org.objectledge.database;
29  
30  import java.sql.Connection;
31  
32  import javax.sql.DataSource;
33  
34  import junit.framework.TestCase;
35  
36  import org.apache.log4j.BasicConfigurator;
37  import org.jcontainer.dna.Logger;
38  import org.jcontainer.dna.impl.DefaultConfiguration;
39  import org.jcontainer.dna.impl.Log4JLogger;
40  import org.objectledge.context.Context;
41  import org.objectledge.pipeline.Valve;
42  
43  /***
44   * 
45   * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
46   * @version $Id: ThreadDataSourceTest.java,v 1.7 2005/10/09 19:43:21 rafal Exp $
47   */
48  public class ThreadDataSourceTest extends TestCase
49  {
50      /***
51       * Constructor for ThreadDataSourceTest.
52       * @param arg0
53       */
54      public ThreadDataSourceTest(String arg0)
55      {
56          super(arg0);
57      }
58      
59      private ThreadDataSource threadDataSource;
60      
61      private Valve guardValve;
62      
63      private Context context;
64      
65      private Logger log;
66      
67      public void setUp(int tracing)
68          throws Exception
69      {
70          BasicConfigurator.resetConfiguration();
71          BasicConfigurator.configure();
72          DefaultConfiguration conf = new DefaultConfiguration("config","","/");
73          DefaultConfiguration url = new DefaultConfiguration("url","","/config");
74          url.setValue("jdbc:hsqldb:."); 
75          conf.addChild(url);    
76          DefaultConfiguration user = new DefaultConfiguration("user","","/config");
77          user.setValue("sa");
78          conf.addChild(user);
79          DataSource dataSource = new HsqldbDataSource(conf);
80          context = new Context();
81          context.clearAttributes();
82          log = new Log4JLogger(org.apache.log4j.Logger.getLogger(ThreadDataSource.class));
83          threadDataSource = new ThreadDataSource(dataSource, tracing, false, null, context, null, log);
84          guardValve = new ThreadDataSource.GuardValve(log);
85      }
86      
87      public void testBasic()
88          throws Exception
89      {
90          setUp(0);
91          Connection c1 = threadDataSource.getConnection();
92          Connection c2 = threadDataSource.getConnection();
93          assertSame(c1, c2);
94          c2.close();
95          c1.close();
96          guardValve.process(context);
97      }
98  
99      public void testUser()
100         throws Exception
101     {
102         setUp(0);
103         Connection c1 = threadDataSource.getConnection("sa","");
104         Connection c2 = threadDataSource.getConnection("sa","");
105         assertSame(c1, c2);
106         c2.close();
107         c1.close();
108         guardValve.process(context);
109     }
110     
111     public void testTooManyCloses()
112         throws Exception
113     {
114         setUp(0);
115         Connection c1 = threadDataSource.getConnection();
116         Connection c2 = threadDataSource.getConnection();
117         assertSame(c1, c2);
118         c2.close();
119         c1.close();
120         try
121         {
122             c1.close();
123             fail("exception expected");
124         }
125         catch(Exception e)
126         {
127             assertEquals("too many close() calls", e.getMessage());
128         }
129         guardValve.process(context);
130     }
131     
132     public void testTooFewCloses()
133         throws Exception
134     {
135         setUp(1);
136         Connection c1 = threadDataSource.getConnection();
137         Connection c2 = threadDataSource.getConnection();
138         assertSame(c1, c2);
139         c2.close();
140         guardValve.process(context);
141     }
142 
143     public void testUserTooFewCloses()
144         throws Exception
145     {
146         setUp(4);
147         Connection c1 = threadDataSource.getConnection("sa","");
148         Connection c2 = threadDataSource.getConnection("sa","");
149         assertSame(c1, c2);
150         c2.close();
151         guardValve.process(context);
152     }
153     
154     public void testNoTracingTooFewCloses()
155         throws Exception
156     {
157         setUp(0);
158         Connection c1 = threadDataSource.getConnection();
159         Connection c2 = threadDataSource.getConnection();
160         assertSame(c1, c2);
161         c2.close();
162         guardValve.process(context);
163     }
164     
165     public void testOutOfOrderTransaction()
166         throws Exception
167     {
168         setUp(0);
169         Transaction transaction = new JotmTransaction(0, 120, context, log, null);
170         Connection c1 = threadDataSource.getConnection();
171         try
172         {
173             transaction.begin();
174             fail("exception expected");
175         }
176         catch(Exception e)
177         {
178             assertEquals("Thread owns open database connection(s) " +
179                     "that would ignore global transaction (see log)", e.getMessage());
180         }
181         finally
182         {
183             DatabaseUtils.close(c1);
184         }
185     }
186 }