Mercurial > stress-tester
changeset 1090:99f8c3835de6
MySqlResponsePacketsDecoder in progress
author | Devel 2 |
---|---|
date | Mon, 11 May 2020 10:59:41 +0200 |
parents | b1c79edc6d5e |
children | fb3d83dfbd17 |
files | stress-tester/src/main/java/com/passus/st/client/mysql/MySqlResponsePacketsDecoder.java stress-tester/src/test/java/com/passus/st/client/mysql/MySqlResponsePacketsDecoderTest.java stress-tester/src/test/resources/pcap/mysql/mysql_query_1000_records.pcap |
diffstat | 3 files changed, 154 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stress-tester/src/main/java/com/passus/st/client/mysql/MySqlResponsePacketsDecoder.java Mon May 11 10:59:41 2020 +0200 @@ -0,0 +1,105 @@ +package com.passus.st.client.mysql; + +import com.passus.data.AbstractDataDecoder; +import com.passus.data.DataUtils; +import com.passus.net.FixedSizeLengthPduX; +import com.passus.net.FixedSizeLengthPduXHandler; +import com.passus.net.PduX; +import com.passus.net.mysql.MySqlDecoder; +import com.passus.net.mysql.MySqlDecoderContext; +import com.passus.net.mysql.MySqlPacket; +import com.passus.net.mysql.MySqlResponseDecoder; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; + +public class MySqlResponsePacketsDecoder extends AbstractDataDecoder<List<MySqlPacket>> { + + private static final Logger LOGGER = LogManager.getLogger(MySqlResponsePacketsDecoder.class); + + private final List<MySqlPacket> packets; + + private final MySqlDecoderContext context; + + private final MySqlPdu pdu; + + public MySqlResponsePacketsDecoder(MySqlDecoderContext context) { + this.context = context; + this.pdu = new MySqlPdu(context); + this.packets = new ArrayList<>(); + } + + @Override + public List<MySqlPacket> getResult() { + return packets; + } + + @Override + public void clear() { + pdu.pdu.clear(); + packets.clear(); + } + + @Override + public void finish() { + pdu.decoder.finish(); + } + + @Override + public int decode(byte[] data, int offset, int length) { + pdu.handle(data, offset, length); + return length; + } + + private class MySqlPdu implements FixedSizeLengthPduXHandler { + + private final MySqlResponseDecoder decoder; + + private final PduX pdu; + + public MySqlPdu(MySqlDecoderContext context) { + decoder = new MySqlResponseDecoder(context); + decoder.context(context); + + pdu = new FixedSizeLengthPduX(this, 3, false); + } + + public void handle(byte[] data, int offset, int length) { + pdu.handle(data, offset, length); + } + + @Override + public void decodeBlockLength(byte[] data, int offset, MutableInt value) { + value.setValue(DataUtils.getInt3LE(data, offset) + 1); + } + + @Override + public void onNewPdu(byte[] data, int offset, int length) { + try { + decoder.decode(data, offset, length); + if (decoder.state() == MySqlDecoder.STATE_FINISHED) { + MySqlPacket packet = decoder.getResult(); + if (packet != null) { + packets.add(packet); + if (context.stage() == MySqlDecoderContext.STAGE_REQUEST) { + state(STATE_FINISHED); + } + } + + decoder.clear(); + } else if (decoder.state() == MySqlDecoder.STATE_ERROR) { + error("Decoder error. " + decoder.getLastError()); + } + } catch (Exception e) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(e.getMessage(), e); + } + + decoder.clear(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stress-tester/src/test/java/com/passus/st/client/mysql/MySqlResponsePacketsDecoderTest.java Mon May 11 10:59:41 2020 +0200 @@ -0,0 +1,49 @@ +package com.passus.st.client.mysql; + +import com.passus.net.mysql.*; +import com.passus.net.packet.Tcp; +import com.passus.net.source.pcap.PcapUtils; +import org.testng.annotations.Test; + +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import static com.passus.data.DataDecoder.STATE_DATA_NEEDED; +import static com.passus.data.DataDecoder.STATE_FINISHED; +import static org.testng.AssertJUnit.assertEquals; + +public class MySqlResponsePacketsDecoderTest { + + @Test + public void testProcess1000Records() { + List<Tcp> tcps = PcapUtils.readTcpPackets("pcap/mysql/mysql_query_1000_records.pcap"); + tcps = tcps.stream().filter(t -> t.hasPayload()).collect(Collectors.toList()); + + MySqlDecoderContext context = new MySqlDecoderContext(); + MySqlRequestDecoder reqDecoder = new MySqlRequestDecoder(context); + MySqlResponsePacketsDecoder respDecoder = new MySqlResponsePacketsDecoder(context); + + Iterator<Tcp> it = tcps.iterator(); + reqDecoder.decode(it.next().getPayload()); + + respDecoder.decode(it.next().getPayload()); + assertEquals(STATE_DATA_NEEDED, respDecoder.state()); + + respDecoder.decode(it.next().getPayload()); + assertEquals(STATE_DATA_NEEDED, respDecoder.state()); + + respDecoder.decode(it.next().getPayload()); + assertEquals(STATE_DATA_NEEDED, respDecoder.state()); + + respDecoder.decode(it.next().getPayload()); + assertEquals(STATE_FINISHED, respDecoder.state()); + + List<MySqlPacket> packets = respDecoder.getResult(); + assertEquals(6, packets.stream().filter(p -> p instanceof MySqlColumnDefinition).count()); + assertEquals(1000, packets.stream().filter(p -> p instanceof MySqlRowResponse).count()); + + reqDecoder.decode(it.next().getPayload()); + + } +} \ No newline at end of file