~pbms-core/pbms/async_read

« back to all changes in this revision

Viewing changes to mybs/java/src/testsuite/regression/DataSourceRegressionTest.java

  • Committer: paul-mccullagh
  • Date: 2008-03-26 11:35:17 UTC
  • Revision ID: paul-mccullagh-afb1610c21464a577ae428d72fc725eb986c05a5
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2002-2006 MySQL AB
 
3
 
 
4
 This program is free software; you can redistribute it and/or modify
 
5
 it under the terms of version 2 of the GNU General Public License as 
 
6
 published by the Free Software Foundation.
 
7
 
 
8
 There are special exceptions to the terms and conditions of the GPL 
 
9
 as it is applied to this software. View the full text of the 
 
10
 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
 
11
 software distribution.
 
12
 
 
13
 This program is distributed in the hope that it will be useful,
 
14
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 GNU General Public License for more details.
 
17
 
 
18
 You should have received a copy of the GNU General Public License
 
19
 along with this program; if not, write to the Free Software
 
20
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 
 
22
 
 
23
 
 
24
 */
 
25
package testsuite.regression;
 
26
 
 
27
import java.io.ByteArrayInputStream;
 
28
import java.io.ByteArrayOutputStream;
 
29
import java.io.File;
 
30
import java.io.ObjectInputStream;
 
31
import java.io.ObjectOutputStream;
 
32
import java.lang.reflect.Method;
 
33
import java.sql.Connection;
 
34
import java.sql.PreparedStatement;
 
35
import java.sql.SQLException;
 
36
import java.sql.Statement;
 
37
import java.util.Hashtable;
 
38
import java.util.Properties;
 
39
 
 
40
import javax.naming.Context;
 
41
import javax.naming.InitialContext;
 
42
import javax.naming.Name;
 
43
import javax.naming.NameParser;
 
44
import javax.naming.RefAddr;
 
45
import javax.naming.Reference;
 
46
import javax.naming.spi.ObjectFactory;
 
47
import javax.sql.ConnectionPoolDataSource;
 
48
import javax.sql.DataSource;
 
49
import javax.sql.PooledConnection;
 
50
 
 
51
import testsuite.BaseTestCase;
 
52
import testsuite.simple.DataSourceTest;
 
53
 
 
54
import com.mysql.jdbc.NonRegisteringDriver;
 
55
import com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker;
 
56
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
 
57
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
 
58
import com.mysql.jdbc.jdbc2.optional.MysqlDataSourceFactory;
 
59
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
 
60
 
 
61
/**
 
62
 * Tests fixes for bugs related to datasources.
 
63
 * 
 
64
 * @author Mark Matthews
 
65
 * 
 
66
 * @version $Id: DataSourceRegressionTest.java,v 1.1.2.1 2005/05/13 18:58:38
 
67
 *          mmatthews Exp $
 
68
 */
 
69
public class DataSourceRegressionTest extends BaseTestCase {
 
70
 
 
71
        public final static String DS_DATABASE_PROP_NAME = "com.mysql.jdbc.test.ds.db";
 
72
 
 
73
        public final static String DS_HOST_PROP_NAME = "com.mysql.jdbc.test.ds.host";
 
74
 
 
75
        public final static String DS_PASSWORD_PROP_NAME = "com.mysql.jdbc.test.ds.password";
 
76
 
 
77
        public final static String DS_PORT_PROP_NAME = "com.mysql.jdbc.test.ds.port";
 
78
 
 
79
        public final static String DS_USER_PROP_NAME = "com.mysql.jdbc.test.ds.user";
 
80
 
 
81
        private Context ctx;
 
82
 
 
83
        private File tempDir;
 
84
 
 
85
        /**
 
86
         * Creates a new DataSourceRegressionTest suite for the given test name
 
87
         * 
 
88
         * @param name
 
89
         *            the name of the testcase to run.
 
90
         */
 
91
        public DataSourceRegressionTest(String name) {
 
92
                super(name);
 
93
 
 
94
                // TODO Auto-generated constructor stub
 
95
        }
 
96
 
 
97
        /**
 
98
         * Runs all test cases in this test suite
 
99
         * 
 
100
         * @param args
 
101
         */
 
102
        public static void main(String[] args) {
 
103
                junit.textui.TestRunner.run(DataSourceTest.class);
 
104
        }
 
105
 
 
106
        /**
 
107
         * Sets up this test, calling registerDataSource() to bind a DataSource into
 
108
         * JNDI, using the FSContext JNDI provider from Sun
 
109
         * 
 
110
         * @throws Exception
 
111
         *             if an error occurs.
 
112
         */
 
113
        public void setUp() throws Exception {
 
114
                super.setUp();
 
115
                createJNDIContext();
 
116
        }
 
117
 
 
118
        /**
 
119
         * Un-binds the DataSource, and cleans up the filesystem
 
120
         * 
 
121
         * @throws Exception
 
122
         *             if an error occurs
 
123
         */
 
124
        public void tearDown() throws Exception {
 
125
                this.ctx.unbind(this.tempDir.getAbsolutePath() + "/test");
 
126
                this.ctx.unbind(this.tempDir.getAbsolutePath() + "/testNoUrl");
 
127
                this.ctx.close();
 
128
                this.tempDir.delete();
 
129
 
 
130
                super.tearDown();
 
131
        }
 
132
 
 
133
        /**
 
134
         * Tests fix for BUG#4808- Calling .close() twice on a PooledConnection
 
135
         * causes NPE.
 
136
         * 
 
137
         * @throws Exception
 
138
         *             if an error occurs.
 
139
         */
 
140
        public void testBug4808() throws Exception {
 
141
                MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
 
142
                ds.setURL(BaseTestCase.dbUrl);
 
143
                PooledConnection closeMeTwice = ds.getPooledConnection();
 
144
                closeMeTwice.close();
 
145
                closeMeTwice.close();
 
146
 
 
147
        }
 
148
 
 
149
        /**
 
150
         * Tests fix for Bug#3848, port # alone parsed incorrectly
 
151
         * 
 
152
         * @throws Exception
 
153
         *             ...
 
154
         */
 
155
        public void testBug3848() throws Exception {
 
156
                String jndiName = "/testBug3848";
 
157
 
 
158
                String databaseName = System.getProperty(DS_DATABASE_PROP_NAME);
 
159
                String userName = System.getProperty(DS_USER_PROP_NAME);
 
160
                String password = System.getProperty(DS_PASSWORD_PROP_NAME);
 
161
                String port = System.getProperty(DS_PORT_PROP_NAME);
 
162
 
 
163
                // Only run this test if at least one of the above are set
 
164
                if ((databaseName != null) || (userName != null) || (password != null)
 
165
                                || (port != null)) {
 
166
                        MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
 
167
 
 
168
                        if (databaseName != null) {
 
169
                                ds.setDatabaseName(databaseName);
 
170
                        }
 
171
 
 
172
                        if (userName != null) {
 
173
                                ds.setUser(userName);
 
174
                        }
 
175
 
 
176
                        if (password != null) {
 
177
                                ds.setPassword(password);
 
178
                        }
 
179
 
 
180
                        if (port != null) {
 
181
                                ds.setPortNumber(Integer.parseInt(port));
 
182
                        }
 
183
 
 
184
                        bindDataSource(jndiName, ds);
 
185
 
 
186
                        ConnectionPoolDataSource boundDs = null;
 
187
 
 
188
                        try {
 
189
                                boundDs = (ConnectionPoolDataSource) lookupDatasourceInJNDI(jndiName);
 
190
 
 
191
                                assertTrue("Datasource not bound", boundDs != null);
 
192
 
 
193
                                Connection dsConn = null;
 
194
 
 
195
                                try {
 
196
                                        dsConn = boundDs.getPooledConnection().getConnection();
 
197
                                } finally {
 
198
                                        if (dsConn != null) {
 
199
                                                dsConn.close();
 
200
                                        }
 
201
                                }
 
202
                        } finally {
 
203
                                if (boundDs != null) {
 
204
                                        this.ctx.unbind(jndiName);
 
205
                                }
 
206
                        }
 
207
                }
 
208
        }
 
209
 
 
210
        /**
 
211
         * Tests that we can get a connection from the DataSource bound in JNDI
 
212
         * during test setup
 
213
         * 
 
214
         * @throws Exception
 
215
         *             if an error occurs
 
216
         */
 
217
        public void testBug3920() throws Exception {
 
218
                String jndiName = "/testBug3920";
 
219
 
 
220
                String databaseName = System.getProperty(DS_DATABASE_PROP_NAME);
 
221
                String userName = System.getProperty(DS_USER_PROP_NAME);
 
222
                String password = System.getProperty(DS_PASSWORD_PROP_NAME);
 
223
                String port = System.getProperty(DS_PORT_PROP_NAME);
 
224
                String serverName = System.getProperty(DS_HOST_PROP_NAME);
 
225
 
 
226
                // Only run this test if at least one of the above are set
 
227
                if ((databaseName != null) || (serverName != null)
 
228
                                || (userName != null) || (password != null) || (port != null)) {
 
229
                        MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
 
230
 
 
231
                        if (databaseName != null) {
 
232
                                ds.setDatabaseName(databaseName);
 
233
                        }
 
234
 
 
235
                        if (userName != null) {
 
236
                                ds.setUser(userName);
 
237
                        }
 
238
 
 
239
                        if (password != null) {
 
240
                                ds.setPassword(password);
 
241
                        }
 
242
 
 
243
                        if (port != null) {
 
244
                                ds.setPortNumber(Integer.parseInt(port));
 
245
                        }
 
246
 
 
247
                        if (serverName != null) {
 
248
                                ds.setServerName(serverName);
 
249
                        }
 
250
 
 
251
                        bindDataSource(jndiName, ds);
 
252
 
 
253
                        ConnectionPoolDataSource boundDs = null;
 
254
 
 
255
                        try {
 
256
                                boundDs = (ConnectionPoolDataSource) lookupDatasourceInJNDI(jndiName);
 
257
 
 
258
                                assertTrue("Datasource not bound", boundDs != null);
 
259
 
 
260
                                Connection dsCon = null;
 
261
                                Statement dsStmt = null;
 
262
 
 
263
                                try {
 
264
                                        dsCon = boundDs.getPooledConnection().getConnection();
 
265
                                        dsStmt = dsCon.createStatement();
 
266
                                        dsStmt.executeUpdate("DROP TABLE IF EXISTS testBug3920");
 
267
                                        dsStmt
 
268
                                                        .executeUpdate("CREATE TABLE testBug3920 (field1 varchar(32))");
 
269
 
 
270
                                        assertTrue(
 
271
                                                        "Connection can not be obtained from data source",
 
272
                                                        dsCon != null);
 
273
                                } finally {
 
274
                                        dsStmt.executeUpdate("DROP TABLE IF EXISTS testBug3920");
 
275
 
 
276
                                        dsStmt.close();
 
277
                                        dsCon.close();
 
278
                                }
 
279
                        } finally {
 
280
                                if (boundDs != null) {
 
281
                                        this.ctx.unbind(jndiName);
 
282
                                }
 
283
                        }
 
284
                }
 
285
        }
 
286
 
 
287
        /** 
 
288
         * Tests fix for BUG#19169 - ConnectionProperties (and thus some
 
289
         * subclasses) are not serializable, even though some J2EE containers
 
290
         * expect them to be.
 
291
         * 
 
292
         * @throws Exception if the test fails.
 
293
         */
 
294
        public void testBug19169() throws Exception {
 
295
                MysqlDataSource toSerialize = new MysqlDataSource();
 
296
                toSerialize.setZeroDateTimeBehavior("convertToNull");
 
297
                
 
298
                boolean testBooleanFlag = !toSerialize.getAllowLoadLocalInfile();
 
299
                toSerialize.setAllowLoadLocalInfile(testBooleanFlag);
 
300
                
 
301
                int testIntFlag = toSerialize.getBlobSendChunkSize() + 1;
 
302
                toSerialize.setBlobSendChunkSize(String.valueOf(testIntFlag));
 
303
                
 
304
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
 
305
                ObjectOutputStream objOut = new ObjectOutputStream(bOut);
 
306
                objOut.writeObject(toSerialize);
 
307
                objOut.flush();
 
308
                
 
309
                ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));
 
310
                
 
311
                MysqlDataSource thawedDs = (MysqlDataSource)objIn.readObject();
 
312
                
 
313
                assertEquals("convertToNull", thawedDs.getZeroDateTimeBehavior());
 
314
                assertEquals(testBooleanFlag, thawedDs.getAllowLoadLocalInfile());
 
315
                assertEquals(testIntFlag, thawedDs.getBlobSendChunkSize());
 
316
        }
 
317
        
 
318
        /**
 
319
         * Tests fix for BUG#20242 - MysqlValidConnectionChecker for JBoss doesn't
 
320
         * work with MySQLXADataSources.
 
321
         * 
 
322
         * @throws Exception if the test fails.
 
323
         */
 
324
        public void testBug20242() throws Exception {
 
325
                if (versionMeetsMinimum(5, 0)) {
 
326
                        try {
 
327
                                Class.forName("org.jboss.resource.adapter.jdbc.ValidConnectionChecker");
 
328
                        } catch (Exception ex) {
 
329
                                return; // class not available for testing
 
330
                        }
 
331
                        
 
332
                        MysqlXADataSource xaDs = new MysqlXADataSource();
 
333
                        xaDs.setUrl(dbUrl);
 
334
                        
 
335
                        MysqlValidConnectionChecker checker = new MysqlValidConnectionChecker();
 
336
                        assertNull(checker.isValidConnection(xaDs.getXAConnection().getConnection()));
 
337
                }       
 
338
        }
 
339
        
 
340
        private void bindDataSource(String name, DataSource ds) throws Exception {
 
341
                this.ctx.bind(this.tempDir.getAbsolutePath() + name, ds);
 
342
        }
 
343
 
 
344
        /**
 
345
         * This method is separated from the rest of the example since you normally
 
346
         * would NOT register a JDBC driver in your code. It would likely be
 
347
         * configered into your naming and directory service using some GUI.
 
348
         * 
 
349
         * @throws Exception
 
350
         *             if an error occurs
 
351
         */
 
352
        private void createJNDIContext() throws Exception {
 
353
                this.tempDir = File.createTempFile("jnditest", null);
 
354
                this.tempDir.delete();
 
355
                this.tempDir.mkdir();
 
356
                this.tempDir.deleteOnExit();
 
357
 
 
358
                MysqlConnectionPoolDataSource ds;
 
359
                Hashtable env = new Hashtable();
 
360
                env.put(Context.INITIAL_CONTEXT_FACTORY,
 
361
                                "com.sun.jndi.fscontext.RefFSContextFactory");
 
362
                this.ctx = new InitialContext(env);
 
363
                assertTrue("Naming Context not created", this.ctx != null);
 
364
                ds = new MysqlConnectionPoolDataSource();
 
365
                ds.setUrl(dbUrl); // from BaseTestCase
 
366
                ds.setDatabaseName("test");
 
367
                this.ctx.bind(this.tempDir.getAbsolutePath() + "/test", ds);
 
368
        }
 
369
 
 
370
        private DataSource lookupDatasourceInJNDI(String jndiName) throws Exception {
 
371
                NameParser nameParser = this.ctx.getNameParser("");
 
372
                Name datasourceName = nameParser.parse(this.tempDir.getAbsolutePath()
 
373
                                + jndiName);
 
374
                Object obj = this.ctx.lookup(datasourceName);
 
375
                DataSource boundDs = null;
 
376
 
 
377
                if (obj instanceof DataSource) {
 
378
                        boundDs = (DataSource) obj;
 
379
                } else if (obj instanceof Reference) {
 
380
                        //
 
381
                        // For some reason, this comes back as a Reference
 
382
                        // instance under CruiseControl !?
 
383
                        //
 
384
                        Reference objAsRef = (Reference) obj;
 
385
                        ObjectFactory factory = (ObjectFactory) Class.forName(
 
386
                                        objAsRef.getFactoryClassName()).newInstance();
 
387
                        boundDs = (DataSource) factory.getObjectInstance(objAsRef,
 
388
                                        datasourceName, this.ctx, new Hashtable());
 
389
                }
 
390
 
 
391
                return boundDs;
 
392
        }
 
393
 
 
394
        public void testCSC4616() throws Exception {
 
395
                MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
 
396
                ds.setURL(BaseTestCase.dbUrl);
 
397
                PooledConnection pooledConn = ds.getPooledConnection();
 
398
                Connection physConn = pooledConn.getConnection();
 
399
                Statement physStatement = physConn.createStatement();
 
400
 
 
401
                Method enableStreamingResultsMethodStmt = Class.forName(
 
402
                                "com.mysql.jdbc.jdbc2.optional.StatementWrapper").getMethod(
 
403
                                "enableStreamingResults", new Class[0]);
 
404
                enableStreamingResultsMethodStmt.invoke(physStatement, new Class[0]);
 
405
                this.rs = physStatement.executeQuery("SELECT 1");
 
406
 
 
407
                try {
 
408
                        physConn.createStatement().executeQuery("SELECT 2");
 
409
                        fail("Should have caught a streaming exception here");
 
410
                } catch (SQLException sqlEx) {
 
411
                        assertTrue(sqlEx.getMessage() != null
 
412
                                        && sqlEx.getMessage().indexOf("Streaming") != -1);
 
413
                } finally {
 
414
                        if (this.rs != null) {
 
415
                                this.rs.close();
 
416
                                this.rs = null;
 
417
                        }
 
418
                }
 
419
 
 
420
                PreparedStatement physPrepStmt = physConn.prepareStatement("SELECT 1");
 
421
                Method enableStreamingResultsMethodPstmt = Class.forName(
 
422
                                "com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper")
 
423
                                .getMethod("enableStreamingResults", new Class[0]);
 
424
                enableStreamingResultsMethodPstmt.invoke(physPrepStmt, new Class[0]);
 
425
 
 
426
                this.rs = physPrepStmt.executeQuery();
 
427
 
 
428
                try {
 
429
                        physConn.createStatement().executeQuery("SELECT 2");
 
430
                        fail("Should have caught a streaming exception here");
 
431
                } catch (SQLException sqlEx) {
 
432
                        assertTrue(sqlEx.getMessage() != null
 
433
                                        && sqlEx.getMessage().indexOf("Streaming") != -1);
 
434
                } finally {
 
435
                        if (this.rs != null) {
 
436
                                this.rs.close();
 
437
                                this.rs = null;
 
438
                        }
 
439
                }
 
440
        }
 
441
 
 
442
        /**
 
443
         * Tests fix for BUG#16791 - NullPointerException in MysqlDataSourceFactory
 
444
         * due to Reference containing RefAddrs with null content.
 
445
         * 
 
446
         * @throws Exception if the test fails
 
447
         */
 
448
        public void testBug16791() throws Exception {
 
449
                MysqlDataSource myDs = new MysqlDataSource();
 
450
                myDs.setUrl(dbUrl);
 
451
                Reference asRef = myDs.getReference();
 
452
                System.out.println(asRef);
 
453
                
 
454
                removeFromRef(asRef, "port");
 
455
                removeFromRef(asRef, NonRegisteringDriver.USER_PROPERTY_KEY);
 
456
                removeFromRef(asRef, NonRegisteringDriver.PASSWORD_PROPERTY_KEY);
 
457
                removeFromRef(asRef, "serverName");
 
458
                removeFromRef(asRef, "databaseName");
 
459
                
 
460
                MysqlDataSource newDs = (MysqlDataSource)new MysqlDataSourceFactory().getObjectInstance(asRef, null, null, null);
 
461
        }
 
462
 
 
463
        private void removeFromRef(Reference ref, String key) {
 
464
                int size = ref.size();
 
465
                
 
466
                for (int i = 0; i < size; i++) {
 
467
                        RefAddr refAddr = ref.get(i);
 
468
                        if (refAddr.getType().equals(key)) {
 
469
                                ref.remove(i);
 
470
                                break;
 
471
                        }
 
472
                }
 
473
        }
 
474
}