]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
b39616d42ecbe394c7711586fc987e9717bf3414
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2    Copyright 2010 Sun Microsystems, Inc.
3    All rights reserved. Use is subject to license terms.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
17 */
18
19 package testsuite.clusterj;
20
21 import java.nio.ByteBuffer;
22 import java.nio.CharBuffer;
23 import java.nio.charset.Charset;
24 import java.nio.charset.CharsetEncoder;
25 import java.nio.charset.CoderResult;
26
27 import java.sql.PreparedStatement;
28 import java.sql.ResultSet;
29 import java.sql.SQLException;
30
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Properties;
34
35 import testsuite.clusterj.model.CharsetLatin1;
36 import testsuite.clusterj.model.CharsetBig5;
37 import testsuite.clusterj.model.CharsetModel;
38 import testsuite.clusterj.model.CharsetSjis;
39 import testsuite.clusterj.model.CharsetUtf8;
40
41 /** Test that all characters in supported character sets can be read and written.
42
43  * 1. Identify which character sets to test.
44  * 2. For each character set, create a table with an id column and three VARCHAR columns 
45  *    (one with length < 256 another with length > 256, and a third with length > 8000)
46  *    with the test character set.
47  * 3. For each table, write a persistent interface that maps the table.
48  * 4. For each persistent interface:
49  *   a) create an empty list of String
50  *   b) create a CharBuffer containing all mappable characters for the character set from the range 0:65535
51  *   c) map the CharBuffer to a ByteBuffer of length equal to the size of the VARCHAR column
52  *   d) create a String from the characters in the CharBuffer that could fit into the column
53  *   e) add the String to the list of String
54  *   f) continue from c) until all characters have been represented in the list of String
55  *   g) remove all rows of the table
56  *   h) use JDBC or clusterj to write a row in the database for each String in the list
57  *   i) use JDBC or clusterj to read all rows and compare the String to the list of Strings
58  *
59  */
60 public class CharsetTest extends AbstractClusterJModelTest {
61
62     @Override
63     public void localSetUp() {
64         createSessionFactory();
65         session = sessionFactory.getSession();
66         setAutoCommit(connection, false);
67     }
68
69     public void testLatin1() {
70         writeJDBCreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.SMALL);
71         writeJDBCreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.MEDIUM);
72         writeJDBCreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.LARGE);
73
74         writeJDBCreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.SMALL);
75         writeJDBCreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.MEDIUM);
76         writeJDBCreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.LARGE);
77
78         writeNDBreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.SMALL);
79         writeNDBreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.MEDIUM);
80         writeNDBreadJDBC("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.LARGE);
81
82         writeNDBreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.SMALL);
83         writeNDBreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.MEDIUM);
84         writeNDBreadNDB("windows-1252", "charsetlatin1", CharsetLatin1.class, ColumnDescriptor.LARGE);
85
86         failOnError();
87     }
88
89     public void testUtf8() {
90         writeJDBCreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.SMALL);
91         writeJDBCreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.MEDIUM);
92         writeJDBCreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.LARGE);
93
94         writeJDBCreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.SMALL);
95         writeJDBCreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.MEDIUM);
96         writeJDBCreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.LARGE);
97
98         writeNDBreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.SMALL);
99         writeNDBreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.MEDIUM);
100         writeNDBreadJDBC("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.LARGE);
101
102         writeNDBreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.SMALL);
103         writeNDBreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.MEDIUM);
104         writeNDBreadNDB("UTF-8", "charsetutf8", CharsetUtf8.class, ColumnDescriptor.LARGE);
105
106         failOnError();
107     }
108
109     public void testSjis() {
110         /* These tests are excluded due to a JDBC error:
111          * java.sql.SQLException: 
112          * Failed to insert charsetsjis at instance 0 errant string: [... 165 167 168... ]
113          * Incorrect string value: '\xC2\xA5\xC2\xA7\xC2\xA8...' for column 'smallcolumn' at row 1
114                                 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
115                                 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
116                                 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
117                                 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
118                                 at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
119                                 at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
120                                 at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
121                                 at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
122                                 at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1356)
123                                 at testsuite.clusterj.CharsetTest.writeToJDBC(CharsetTest.java:317)
124         writeJDBCreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.SMALL);
125         writeJDBCreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.MEDIUM);
126         writeJDBCreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.LARGE);
127          */
128
129         writeNDBreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.SMALL);
130         writeNDBreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.MEDIUM);
131         writeNDBreadJDBC("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.LARGE);
132
133         writeNDBreadNDB("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.SMALL);
134         writeNDBreadNDB("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.MEDIUM);
135         writeNDBreadNDB("SJIS", "charsetsjis", CharsetSjis.class, ColumnDescriptor.LARGE);
136
137         failOnError();
138     }
139
140     public void testBig5() {
141         writeJDBCreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.SMALL);
142         writeJDBCreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.MEDIUM);
143         writeJDBCreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.LARGE);
144
145         writeJDBCreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.SMALL);
146         writeJDBCreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.MEDIUM);
147         writeJDBCreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.LARGE);
148
149         writeNDBreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.SMALL);
150         writeNDBreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.MEDIUM);
151         writeNDBreadJDBC("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.LARGE);
152
153         writeNDBreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.SMALL);
154         writeNDBreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.MEDIUM);
155         writeNDBreadNDB("big5", "charsetbig5", CharsetBig5.class, ColumnDescriptor.LARGE);
156
157         failOnError();
158     }
159
160     protected void writeJDBCreadJDBC(String charsetName, String tableName, Class<? extends CharsetModel> modelClass,
161             ColumnDescriptor columnDescriptor) {
162         removeAll(modelClass);
163         List<String> result = null;
164         List<String> strings = generateStrings(columnDescriptor, charsetName);
165         List<CharsetModel> instances = generateInstances(columnDescriptor, modelClass, strings);
166         writeToJDBC(columnDescriptor, tableName, instances);
167         result = readFromJDBC(columnDescriptor, tableName);
168         if (debug) System.out.println("Returned results of size " + result.size());
169 //        if (debug) System.out.println("Results:\n" + dump(result));
170         verify("writeJDBCreadJDBC", strings, result, columnDescriptor);
171     }
172
173     protected void writeJDBCreadNDB(String charsetName, String tableName, Class<? extends CharsetModel> modelClass,
174             ColumnDescriptor columnDescriptor) {
175         removeAll(modelClass);
176         List<String> result = null;
177         List<String> strings = generateStrings(columnDescriptor, charsetName);
178         List<CharsetModel> instances = generateInstances(columnDescriptor, modelClass, strings);
179         writeToJDBC(columnDescriptor, tableName, instances);
180         result = readFromNDB(columnDescriptor, modelClass);
181         if (debug) System.out.println("Returned results of size " + result.size());
182 //        if (debug) System.out.println("Results: " + dump(result));
183         verify("writeJDBCreadNDB", strings, result, columnDescriptor);
184     }
185
186     protected void writeNDBreadJDBC(String charsetName, String tableName, Class<? extends CharsetModel> modelClass,
187             ColumnDescriptor columnDescriptor) {
188         removeAll(modelClass);
189         List<String> result = null;
190         List<String> strings = generateStrings(columnDescriptor, charsetName);
191         List<CharsetModel> instances = generateInstances(columnDescriptor, modelClass, strings);
192         writeToNDB(columnDescriptor, instances);
193         result = readFromJDBC(columnDescriptor, tableName);
194         if (debug) System.out.println("Returned results of size " + result.size());
195 //        if (debug) System.out.println("Results: " + dump(result));
196         verify("writeNDBreadJDBC", strings, result, columnDescriptor);
197     }
198
199     protected void writeNDBreadNDB(String charsetName, String tableName, Class<? extends CharsetModel> modelClass,
200             ColumnDescriptor columnDescriptor) {
201         removeAll(modelClass);
202         List<String> result = null;
203         List<String> strings = generateStrings(columnDescriptor, charsetName);
204         List<CharsetModel> instances = generateInstances(columnDescriptor, modelClass, strings);
205         writeToNDB(columnDescriptor, instances);
206         result = readFromNDB(columnDescriptor, modelClass);
207         if (debug) System.out.println("Returned results of size " + result.size());
208 //        if (debug) System.out.println("Results: " + dump(result));
209         verify("writeNDBreadNDB", strings, result, columnDescriptor);
210     }
211
212     private void verify(String where, List<String> expecteds, List<String> actuals, ColumnDescriptor columnDescriptor) {
213         int maxErrors = 10;
214         for (int i = 0; i < expecteds.size(); ++i) {
215             String expected = expecteds.get(i);
216             String actual = actuals.get(i);
217             int expectedLength = expected.length();
218             int actualLength = actual.length();
219             errorIfNotEqual(where + " got failure on size of column data for column width " + columnDescriptor.columnWidth + " at row " + i, expectedLength, actualLength);
220             if (expectedLength != actualLength) 
221                 continue;
222             for (int j = 0; j < expected.length(); ++j) {
223                 if (--maxErrors > 0) {
224                     errorIfNotEqual("Failure to match column data for column width " + columnDescriptor.columnWidth + " at row " + i + " column " + j,
225                             expected.codePointAt(j), actual.codePointAt(j));
226                 }
227             }
228         }
229     }
230
231     protected List<String> generateStrings(ColumnDescriptor columnDescriptor,
232             String charsetName) {
233         List<String> result = new ArrayList<String>();
234         Charset charset = Charset.forName(charsetName);
235         CharBuffer allChars = CharBuffer.allocate(65536);
236         CharsetEncoder encoder = charset.newEncoder();
237        // add all encodable characters to the buffer
238         int count = 0;
239 //        for (int i = 0; i < 65536; ++i) {
240         for (int i = 0; i < 65536; ++i) {
241             Character ch = (char)i;
242             if (encoder.canEncode(ch)) {
243                 allChars.append(ch);
244                 ++count;
245             }
246         }
247         if (debug) System.out.print(charsetName + " has " + count + " encodable characters");
248         allChars.flip();
249
250         int width = columnDescriptor.getColumnWidth();
251         // encode all the characters that fit into the output byte buffer
252         boolean done = false;
253         byte[] bytes = new byte[width];
254         while (!done) {
255             int begin = allChars.position();
256             allChars.mark();
257             ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
258             CoderResult coderResult = encoder.encode(allChars, byteBuffer, false);
259             int end = allChars.position();
260             int length = end - begin;
261             if (length == 0) {
262                 done = true;
263                 continue;
264             }
265             char[] chars = new char[length];
266             allChars.reset();
267             allChars.get(chars, 0, length);
268             String encodable = String.copyValueOf(chars);
269             result.add(encodable);
270             if (coderResult.isUnderflow()) {
271                 done = true;
272             }
273         }
274         if (debug) System.out.println(" in " + result.size() + " row(s) of size " + columnDescriptor.columnWidth);
275         return result;
276     }
277
278     protected List<CharsetModel> generateInstances(ColumnDescriptor columnDescriptor,
279             Class<? extends CharsetModel> modelClass, List<String> strings) {
280         List<CharsetModel> result = new ArrayList<CharsetModel>();
281         for (int i = 0; i < strings.size(); ++i) {
282             CharsetModel instance = session.newInstance(modelClass);
283             instance.setId(i);
284             columnDescriptor.set(instance, strings.get(i));
285             result.add(instance);
286         }
287         if (debug) System.out.println("Created " + result.size() + " instances of " + modelClass.getName());
288         return result;
289     }
290
291     protected void writeToJDBC(ColumnDescriptor columnDescriptor,
292             String tableName, List<CharsetModel> instances) {
293         StringBuffer buffer = new StringBuffer("INSERT INTO ");
294         buffer.append(tableName);
295         buffer.append(" (id, ");
296         buffer.append(columnDescriptor.getColumnName());
297         buffer.append(") VALUES (?, ?)");
298         String statement = buffer.toString();
299         if (debug) System.out.println(statement);
300         PreparedStatement preparedStatement = null;
301         int i = 0;
302         String value = "";
303         try {
304             Properties extraProperties = new Properties();
305             extraProperties.put("characterEncoding", "utf8");
306             getConnection(extraProperties);
307             setAutoCommit(connection, false);
308             preparedStatement = connection.prepareStatement(statement);
309             if (debug) System.out.println(preparedStatement.toString());
310             for (i = 0; i < instances.size(); ++i) {
311                 CharsetModel instance = instances.get(i);
312                 preparedStatement.setInt(1, instance.getId());
313                 value = columnDescriptor.get(instance);
314                 preparedStatement.setString(2, value);
315 //                if (debug) System.out.println("Value set to column is size " + value.length());
316 //                if (debug) System.out.println(" value " + value);
317                 preparedStatement.execute();
318             }
319             connection.commit();
320         } catch (SQLException e) {
321             throw new RuntimeException("Failed to insert " + tableName + " at instance " + i + " errant string: " + dump(value), e);
322         }
323     }
324
325     protected void writeToNDB(ColumnDescriptor columnDescriptor, List<CharsetModel> instances) {
326         session.currentTransaction().begin();
327         for (CharsetModel instance: instances) {
328             session.makePersistent(instance);
329         }
330         session.currentTransaction().commit();
331     }
332
333     protected List<String> readFromNDB(ColumnDescriptor columnDescriptor, 
334             Class<? extends CharsetModel> modelClass) {
335         List<String> result = new ArrayList<String>();
336         session.currentTransaction().begin();
337         int i = 0;
338         boolean done = false;
339         while (!done) {
340             CharsetModel instance = session.find(modelClass, i++);
341             if (instance != null) {
342                 result.add(columnDescriptor.get(instance));
343             } else {
344                 done = true;
345             }
346         }
347         session.currentTransaction().commit();
348         return result;
349     }
350
351     protected List<String> readFromJDBC(ColumnDescriptor columnDescriptor,
352             String tableName) {
353         List<String> result = new ArrayList<String>();
354         StringBuffer buffer = new StringBuffer("SELECT id, ");
355         buffer.append(columnDescriptor.getColumnName());
356         buffer.append(" FROM ");
357         buffer.append(tableName);
358         buffer.append(" ORDER BY ID");
359         String statement = buffer.toString();
360         if (debug) System.out.println(statement);
361         PreparedStatement preparedStatement = null;
362         int i = 0;
363         try {
364             preparedStatement = connection.prepareStatement(statement);
365             ResultSet rs = preparedStatement.executeQuery();
366             while (rs.next()) {
367                 String columnData = rs.getString(2);
368                 result.add(columnData);
369                 ++i;
370             }
371             connection.commit();
372         } catch (SQLException e) {
373             throw new RuntimeException("Failed to read " + tableName + " at instance " + i, e);
374         }
375         return result;
376     }
377
378     protected enum ColumnDescriptor {
379         SMALL(200, "smallcolumn", new InstanceHandler() {
380             public void set(CharsetModel instance, String value) {
381                 instance.setSmallColumn(value);
382             }
383             public String get(CharsetModel instance) {
384                 return instance.getSmallColumn();
385             }
386         }),
387         MEDIUM(500, "mediumcolumn", new InstanceHandler() {
388             public void set(CharsetModel instance, String value) {
389                 instance.setMediumColumn(value);
390             }
391             public String get(CharsetModel instance) {
392                 return instance.getMediumColumn();
393             }
394         }),
395         LARGE(10000, "largecolumn", new InstanceHandler() {
396             public void set(CharsetModel instance, String value) {
397                 instance.setLargeColumn(value);
398             }
399             public String get(CharsetModel instance) {
400                 return instance.getLargeColumn();
401             }
402         });
403
404         private int columnWidth;
405
406         private String columnName;
407
408         private InstanceHandler instanceHandler;
409
410         public String getColumnName() {
411             return columnName;
412         }
413
414         public String get(CharsetModel instance) {
415             return instanceHandler.get(instance);
416         }
417
418         public void set(CharsetModel instance, String string) {
419             this.instanceHandler.set(instance, string);
420         }
421
422         public int getColumnWidth() {
423             return columnWidth;
424         }
425
426         private ColumnDescriptor(int width, String name, InstanceHandler instanceHandler) {
427             this.columnWidth = width;
428             this.columnName = name;
429             this.instanceHandler = instanceHandler;
430         }
431
432         private interface InstanceHandler {
433             void set(CharsetModel instance, String value);
434             String get(CharsetModel instance);
435             }
436
437     }
438
439     /** The instances for testing. */
440     protected List<CharsetModel> charsetTypes = new ArrayList<CharsetModel>();
441
442 }