001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.apache.mina.filter.codec.textline;
021:
022: import java.nio.charset.Charset;
023: import java.nio.charset.CharsetEncoder;
024:
025: import junit.framework.Assert;
026: import junit.framework.TestCase;
027:
028: import org.apache.mina.common.IoBuffer;
029: import org.apache.mina.filter.codec.ProtocolCodecSession;
030: import org.apache.mina.filter.codec.ProtocolDecoderOutput;
031: import org.apache.mina.filter.codec.RecoverableProtocolDecoderException;
032:
033: /**
034: * Tests {@link TextLineDecoder}.
035: *
036: * @author The Apache MINA Project (dev@mina.apache.org)
037: * @version $Rev: 608906 $, $Date: 2008-01-04 09:29:40 -0700 (Fri, 04 Jan 2008) $
038: */
039: public class TextLineDecoderTest extends TestCase {
040: public static void main(String[] args) {
041: junit.textui.TestRunner.run(TextLineDecoderTest.class);
042: }
043:
044: public void testNormalDecode() throws Exception {
045: TextLineDecoder decoder = new TextLineDecoder(Charset
046: .forName("UTF-8"), LineDelimiter.WINDOWS);
047:
048: CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
049: ProtocolCodecSession session = new ProtocolCodecSession();
050: ProtocolDecoderOutput out = session.getDecoderOutput();
051: IoBuffer in = IoBuffer.allocate(16);
052:
053: // Test one decode and one output
054: in.putString("ABC\r\n", encoder);
055: in.flip();
056: decoder.decode(session, in, out);
057: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
058: Assert.assertEquals("ABC", session.getDecoderOutputQueue()
059: .poll());
060:
061: // Test two decode and one output
062: in.clear();
063: in.putString("DEF", encoder);
064: in.flip();
065: decoder.decode(session, in, out);
066: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
067: in.clear();
068: in.putString("GHI\r\n", encoder);
069: in.flip();
070: decoder.decode(session, in, out);
071: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
072: Assert.assertEquals("DEFGHI", session.getDecoderOutputQueue()
073: .poll());
074:
075: // Test one decode and two output
076: in.clear();
077: in.putString("JKL\r\nMNO\r\n", encoder);
078: in.flip();
079: decoder.decode(session, in, out);
080: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
081: Assert.assertEquals("JKL", session.getDecoderOutputQueue()
082: .poll());
083: Assert.assertEquals("MNO", session.getDecoderOutputQueue()
084: .poll());
085:
086: // Test aborted delimiter (DIRMINA-506)
087: in.clear();
088: in.putString("ABC\r\r\n", encoder);
089: in.flip();
090: decoder.decode(session, in, out);
091: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
092: Assert.assertEquals("ABC\r", session.getDecoderOutputQueue()
093: .poll());
094:
095: // Test splitted long delimiter
096: decoder = new TextLineDecoder(Charset.forName("UTF-8"),
097: new LineDelimiter("\n\n\n"));
098: in.clear();
099: in.putString("PQR\n", encoder);
100: in.flip();
101: decoder.decode(session, in, out);
102: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
103: in.clear();
104: in.putString("\n", encoder);
105: in.flip();
106: decoder.decode(session, in, out);
107: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
108: in.clear();
109: in.putString("\n", encoder);
110: in.flip();
111: decoder.decode(session, in, out);
112: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
113: Assert.assertEquals("PQR", session.getDecoderOutputQueue()
114: .poll());
115:
116: // Test splitted long delimiter which produces two output
117: decoder = new TextLineDecoder(Charset.forName("UTF-8"),
118: new LineDelimiter("\n\n\n"));
119: in.clear();
120: in.putString("PQR\n", encoder);
121: in.flip();
122: decoder.decode(session, in, out);
123: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
124: in.clear();
125: in.putString("\n", encoder);
126: in.flip();
127: decoder.decode(session, in, out);
128: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
129: in.clear();
130: in.putString("\nSTU\n\n\n", encoder);
131: in.flip();
132: decoder.decode(session, in, out);
133: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
134: Assert.assertEquals("PQR", session.getDecoderOutputQueue()
135: .poll());
136: Assert.assertEquals("STU", session.getDecoderOutputQueue()
137: .poll());
138:
139: // Test splitted long delimiter mixed with partial non-delimiter.
140: decoder = new TextLineDecoder(Charset.forName("UTF-8"),
141: new LineDelimiter("\n\n\n"));
142: in.clear();
143: in.putString("PQR\n", encoder);
144: in.flip();
145: decoder.decode(session, in, out);
146: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
147: in.clear();
148: in.putString("X\n", encoder);
149: in.flip();
150: decoder.decode(session, in, out);
151: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
152: in.clear();
153: in.putString("\n\nSTU\n\n\n", encoder);
154: in.flip();
155: decoder.decode(session, in, out);
156: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
157: Assert.assertEquals("PQR\nX", session.getDecoderOutputQueue()
158: .poll());
159: Assert.assertEquals("STU", session.getDecoderOutputQueue()
160: .poll());
161: }
162:
163: public void testAutoDecode() throws Exception {
164: TextLineDecoder decoder = new TextLineDecoder(Charset
165: .forName("UTF-8"), LineDelimiter.AUTO);
166:
167: CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
168: ProtocolCodecSession session = new ProtocolCodecSession();
169: ProtocolDecoderOutput out = session.getDecoderOutput();
170: IoBuffer in = IoBuffer.allocate(16);
171:
172: // Test one decode and one output
173: in.putString("ABC\r\n", encoder);
174: in.flip();
175: decoder.decode(session, in, out);
176: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
177: Assert.assertEquals("ABC", session.getDecoderOutputQueue()
178: .poll());
179:
180: // Test two decode and one output
181: in.clear();
182: in.putString("DEF", encoder);
183: in.flip();
184: decoder.decode(session, in, out);
185: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
186: in.clear();
187: in.putString("GHI\r\n", encoder);
188: in.flip();
189: decoder.decode(session, in, out);
190: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
191: Assert.assertEquals("DEFGHI", session.getDecoderOutputQueue()
192: .poll());
193:
194: // Test one decode and two output
195: in.clear();
196: in.putString("JKL\r\nMNO\r\n", encoder);
197: in.flip();
198: decoder.decode(session, in, out);
199: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
200: Assert.assertEquals("JKL", session.getDecoderOutputQueue()
201: .poll());
202: Assert.assertEquals("MNO", session.getDecoderOutputQueue()
203: .poll());
204:
205: // Test multiple '\n's
206: in.clear();
207: in.putString("\n\n\n", encoder);
208: in.flip();
209: decoder.decode(session, in, out);
210: Assert.assertEquals(3, session.getDecoderOutputQueue().size());
211: Assert.assertEquals("", session.getDecoderOutputQueue().poll());
212: Assert.assertEquals("", session.getDecoderOutputQueue().poll());
213: Assert.assertEquals("", session.getDecoderOutputQueue().poll());
214:
215: // Test splitted long delimiter (\r\r\n)
216: in.clear();
217: in.putString("PQR\r", encoder);
218: in.flip();
219: decoder.decode(session, in, out);
220: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
221: in.clear();
222: in.putString("\r", encoder);
223: in.flip();
224: decoder.decode(session, in, out);
225: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
226: in.clear();
227: in.putString("\n", encoder);
228: in.flip();
229: decoder.decode(session, in, out);
230: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
231: Assert.assertEquals("PQR", session.getDecoderOutputQueue()
232: .poll());
233:
234: // Test splitted long delimiter (\r\r\n) which produces two output
235: in.clear();
236: in.putString("PQR\r", encoder);
237: in.flip();
238: decoder.decode(session, in, out);
239: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
240: in.clear();
241: in.putString("\r", encoder);
242: in.flip();
243: decoder.decode(session, in, out);
244: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
245: in.clear();
246: in.putString("\nSTU\r\r\n", encoder);
247: in.flip();
248: decoder.decode(session, in, out);
249: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
250: Assert.assertEquals("PQR", session.getDecoderOutputQueue()
251: .poll());
252: Assert.assertEquals("STU", session.getDecoderOutputQueue()
253: .poll());
254:
255: // Test splitted long delimiter mixed with partial non-delimiter.
256: in.clear();
257: in.putString("PQR\r", encoder);
258: in.flip();
259: decoder.decode(session, in, out);
260: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
261: in.clear();
262: in.putString("X\r", encoder);
263: in.flip();
264: decoder.decode(session, in, out);
265: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
266: in.clear();
267: in.putString("\r\nSTU\r\r\n", encoder);
268: in.flip();
269: decoder.decode(session, in, out);
270: Assert.assertEquals(2, session.getDecoderOutputQueue().size());
271: Assert.assertEquals("PQR\rX", session.getDecoderOutputQueue()
272: .poll());
273: Assert.assertEquals("STU", session.getDecoderOutputQueue()
274: .poll());
275: }
276:
277: public void testOverflow() throws Exception {
278: TextLineDecoder decoder = new TextLineDecoder(Charset
279: .forName("UTF-8"), LineDelimiter.AUTO);
280: decoder.setMaxLineLength(3);
281:
282: CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
283: ProtocolCodecSession session = new ProtocolCodecSession();
284: ProtocolDecoderOutput out = session.getDecoderOutput();
285: IoBuffer in = IoBuffer.allocate(16);
286:
287: // Make sure the overflow exception is not thrown until
288: // the delimiter is encountered.
289: in.putString("A", encoder).flip().mark();
290: decoder.decode(session, in.reset().mark(), out);
291: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
292: decoder.decode(session, in.reset().mark(), out);
293: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
294: decoder.decode(session, in.reset().mark(), out);
295: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
296: decoder.decode(session, in.reset().mark(), out);
297: Assert.assertEquals(0, session.getDecoderOutputQueue().size());
298:
299: in.clear().putString("A\r\nB\r\n", encoder).flip();
300: try {
301: decoder.decode(session, in, out);
302: Assert.fail();
303: } catch (RecoverableProtocolDecoderException e) {
304: // Success!
305: }
306:
307: decoder.decode(session, in, out);
308: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
309: Assert
310: .assertEquals("B", session.getDecoderOutputQueue()
311: .poll());
312:
313: // Make sure OOM is not thrown.
314: System.gc();
315: long oldFreeMemory = Runtime.getRuntime().freeMemory();
316: in = IoBuffer.allocate(1048576 * 16).sweep((byte) ' ').mark();
317: for (int i = 0; i < 10; i++) {
318: decoder.decode(session, in.reset().mark(), out);
319: Assert.assertEquals(0, session.getDecoderOutputQueue()
320: .size());
321:
322: // Memory consumption should be minimal.
323: Assert.assertTrue(Runtime.getRuntime().freeMemory()
324: - oldFreeMemory < 1048576);
325: }
326:
327: in.clear().putString("C\r\nD\r\n", encoder).flip();
328: try {
329: decoder.decode(session, in, out);
330: Assert.fail();
331: } catch (RecoverableProtocolDecoderException e) {
332: // Success!
333: }
334:
335: decoder.decode(session, in, out);
336: Assert.assertEquals(1, session.getDecoderOutputQueue().size());
337: Assert
338: .assertEquals("D", session.getDecoderOutputQueue()
339: .poll());
340:
341: // Memory consumption should be minimal.
342: Assert.assertTrue(Runtime.getRuntime().freeMemory()
343: - oldFreeMemory < 1048576);
344: }
345: }
|