Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mina-filter-compression/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
</dependency>

<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@ public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) t
throw new IllegalStateException("Only one " + CompressionFilter.class + " is permitted.");
}

Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER, maxDecompressedSize,
Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_DEFLATER, maxDecompressedSize,
maxDecompressRatio, decompressRatioMinSize);
Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER, maxDecompressedSize,
Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER, maxDecompressedSize,
maxDecompressRatio, decompressRatioMinSize);

IoSession session = parent.getSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,192 +19,112 @@
*/
package org.apache.mina.filter.compression;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.DefaultWriteRequest;
import org.apache.mina.core.write.WriteRequest;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

/**
*
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
@Ignore
public class CompressionFilterTest {
/*
private MockControl mockSession;

private MockControl mockNextFilter;

private MockControl mockIoFilterChain;

private IoSession session;

private NextFilter nextFilter;

private IoFilterChain ioFilterChain;
// the sample data to be used for testing
private static final String STR_COMPRESS = repeat("The quick brown fox jumps over the lazy dog. ", 25);

private CompressionFilter filter;

private Zlib deflater;

private Zlib inflater;
private IoSession session;

private Zlib actualDeflater;
private IoFilterChain filterChain;

private Zlib actualInflater;
private NextFilter nextFilter;

// the sample data to be used for testing
String strCompress = "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. "
+ "The quick brown fox jumps over the lazy dog. " + "The quick brown fox jumps over the lazy dog. ";
private static String repeat(String value, int count) {
StringBuilder builder = new StringBuilder(value.length() * count);
for (int i = 0; i < count; i++) {
builder.append(value);
}
return builder.toString();
}

@Before
public void setUp() {
// create the necessary mock controls.
mockSession = MockControl.createControl(IoSession.class);
mockNextFilter = MockControl.createControl(NextFilter.class);
mockIoFilterChain = MockControl.createControl(IoFilterChain.class);

// set the default matcher
mockNextFilter.setDefaultMatcher(new DataMatcher());

session = (IoSession) mockSession.getMock();
nextFilter = (NextFilter) mockNextFilter.getMock();
ioFilterChain = (IoFilterChain) mockIoFilterChain.getMock();

// create an instance of the filter
filter = new CompressionFilter(CompressionFilter.COMPRESSION_MAX);

// deflater and inflater that will be used by the filter
deflater = new Zlib(Zlib.COMPRESSION_MAX, Zlib.MODE_DEFLATER);
inflater = new Zlib(Zlib.COMPRESSION_MAX, Zlib.MODE_INFLATER);

// create instances of the deflater and inflater to help test the output
actualDeflater = new Zlib(Zlib.COMPRESSION_MAX, Zlib.MODE_DEFLATER);
actualInflater = new Zlib(Zlib.COMPRESSION_MAX, Zlib.MODE_INFLATER);
// a mock session whose attributes are stored in a real map, so that the deflater and inflater
// created by onPreAdd() are actually retrieved by filterWrite() and messageReceived().
session = mock(IoSession.class);
final Map<Object, Object> attributes = new HashMap<>();
when(session.setAttribute(any(), any()))
.thenAnswer(invocation -> attributes.put(invocation.getArgument(0), invocation.getArgument(1)));
when(session.getAttribute(any())).thenAnswer(invocation -> attributes.get(invocation.getArgument(0)));
when(session.containsAttribute(any())).thenAnswer(invocation -> attributes.containsKey(invocation.getArgument(0)));
when(session.removeAttribute(any())).thenAnswer(invocation -> attributes.remove(invocation.getArgument(0)));

filterChain = mock(IoFilterChain.class);
when(filterChain.contains(CompressionFilter.class)).thenReturn(false);
when(filterChain.getSession()).thenReturn(session);

nextFilter = mock(NextFilter.class);
}

@Test
public void testCompression() throws Exception {
// prepare the input data
IoBuffer buf = IoBuffer.wrap(strCompress.getBytes(StandardCharsets.UTF_8));
IoBuffer actualOutput = actualDeflater.deflate(buf);
buf.flip();
WriteRequest writeRequest = new DefaultWriteRequest(buf);
public void testCompressionRoundTrip() throws Exception {
filter.onPreAdd(filterChain, "CompressionFilter", nextFilter);

// record all the mock calls
ioFilterChain.contains(CompressionFilter.class);
mockIoFilterChain.setReturnValue(false);

ioFilterChain.getSession();
mockIoFilterChain.setReturnValue(session);

session.setAttribute(CompressionFilter.class.getName() + ".Deflater", deflater);
mockSession.setDefaultMatcher(new DataMatcher());
mockSession.setReturnValue(null, MockControl.ONE);

session.setAttribute(CompressionFilter.class.getName() + ".Inflater", inflater);
mockSession.setReturnValue(null, MockControl.ONE);

session.containsAttribute(CompressionFilter.DISABLE_COMPRESSION_ONCE);
mockSession.setReturnValue(false);

session.getAttribute(CompressionFilter.class.getName() + ".Deflater");
mockSession.setReturnValue(deflater);

nextFilter.filterWrite(session, new DefaultWriteRequest(actualOutput));

// switch to playback mode
mockSession.replay();
mockIoFilterChain.replay();
mockNextFilter.replay();

// make the actual calls on the filter
filter.onPreAdd(ioFilterChain, "CompressionFilter", nextFilter);
IoBuffer input = IoBuffer.wrap(STR_COMPRESS.getBytes(StandardCharsets.UTF_8));
WriteRequest writeRequest = new DefaultWriteRequest(input);
filter.filterWrite(nextFilter, session, writeRequest);

// verify that all the calls happened as recorded
mockNextFilter.verify();
// capture the compressed buffer forwarded down the chain
ArgumentCaptor<WriteRequest> writeCaptor = ArgumentCaptor.forClass(WriteRequest.class);
verify(nextFilter).filterWrite(eq(session), writeCaptor.capture());
IoBuffer compressed = (IoBuffer) writeCaptor.getValue().getMessage();

assertTrue(true);
// feeding the compressed buffer back in must reproduce the original payload
filter.messageReceived(nextFilter, session, compressed);
ArgumentCaptor<Object> receiveCaptor = ArgumentCaptor.forClass(Object.class);
verify(nextFilter).messageReceived(eq(session), receiveCaptor.capture());
IoBuffer decompressed = (IoBuffer) receiveCaptor.getValue();

assertEquals(STR_COMPRESS, decompressed.getString(StandardCharsets.UTF_8.newDecoder()));
}

/**
* Regression guard: onPreAdd() must register the deflater in deflate mode and the inflater in
* inflate mode, not the other way round. Verified by checking each rejects the opposite operation.
*/
@Test
public void testDecompression() throws Exception {
// prepare the input data
IoBuffer buf = IoBuffer.wrap(strCompress.getBytes(StandardCharsets.UTF_8));
IoBuffer byteInput = actualDeflater.deflate(buf);
IoBuffer actualOutput = actualInflater.inflate(byteInput);
public void testDeflaterAndInflaterNotSwapped() throws Exception {
filter.onPreAdd(filterChain, "CompressionFilter", nextFilter);

// record all the mock calls
ioFilterChain.contains(CompressionFilter.class);
mockIoFilterChain.setReturnValue(false);
IoBuffer input = IoBuffer.wrap(STR_COMPRESS.getBytes(StandardCharsets.UTF_8));

ioFilterChain.getSession();
mockIoFilterChain.setReturnValue(session);
Zlib deflater = (Zlib) session.getAttribute(new AttributeKey(CompressionFilter.class, "deflater"));
assertNotNull(deflater);
assertThrows(IllegalStateException.class, () -> deflater.inflate(input));

session.setAttribute(CompressionFilter.class.getName() + ".Deflater", deflater);
mockSession.setDefaultMatcher(new DataMatcher());
mockSession.setReturnValue(null, MockControl.ONE);

session.setAttribute(CompressionFilter.class.getName() + ".Inflater", inflater);
mockSession.setReturnValue(null, MockControl.ONE);

session.getAttribute(CompressionFilter.class.getName() + ".Inflater");
mockSession.setReturnValue(inflater);

nextFilter.messageReceived(session, actualOutput);

// switch to playback mode
mockSession.replay();
mockIoFilterChain.replay();
mockNextFilter.replay();

// make the actual calls on the filter
filter.onPreAdd(ioFilterChain, "CompressionFilter", nextFilter);
filter.messageReceived(nextFilter, session, byteInput);

// verify that all the calls happened as recorded
mockNextFilter.verify();

assertTrue(true);
}

/**
* A matcher used to check if the actual and expected outputs matched
*
class DataMatcher extends AbstractMatcher {
@Override
protected boolean argumentMatches(Object arg0, Object arg1) {
// we need to only verify the ByteBuffer output
if (arg0 instanceof WriteRequest) {
WriteRequest expected = (WriteRequest) arg0;
WriteRequest actual = (WriteRequest) arg1;
IoBuffer bExpected = (IoBuffer) expected.getMessage();
IoBuffer bActual = (IoBuffer) actual.getMessage();
return bExpected.equals(bActual);
}
return true;
}
Zlib inflater = (Zlib) session.getAttribute(new AttributeKey(CompressionFilter.class, "inflater"));
assertNotNull(inflater);
assertThrows(IllegalStateException.class, () -> inflater.deflate(input));
}
*/
}
Loading