<commit_before>package io.sniffy.socket;

import io.sniffy.Sniffy;
import io.sniffy.Spy;
import io.sniffy.SpyConfiguration;
import io.sniffy.ThreadMetaData;
import io.sniffy.configuration.SniffyConfiguration;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Stories;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.*;

public class CaptureTrafficTest extends BaseSocketTest {

    @Test
    @Stories({"issues/400", "issues/401"})
    public void testTrafficCapture() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            performSocketOperation();

            Thread thread = new Thread(this::performSocketOperation);
            thread.start();
            thread.join();

            Map<SocketMetaData, List<NetworkPacket>> networkTraffic = spy.getNetworkTraffic();

            for (Map.Entry<SocketMetaData, List<NetworkPacket>> entry : networkTraffic.entrySet()) {

                SocketMetaData socketMetaData = entry.getKey();

                Protocol protocol = socketMetaData.getProtocol(); // say TCP
                String hostName = socketMetaData.getAddress().getHostName(); // say "hostname.acme.com"
                int port = socketMetaData.getAddress().getPort(); // say 443

                assertEquals(Protocol.TCP, protocol);
                assertEquals(localhost.getHostName(), hostName);
                assertEquals(echoServerRule.getBoundPort(), port);

                String stackTrace = socketMetaData.getStackTrace();// optional stacktrace for operation as a String
                ThreadMetaData threadMetaData = socketMetaData.getThreadMetaData();// information about thread which performed the operation

                assertNull(stackTrace);
                assertNull(threadMetaData);

                boolean nextPacketMustBeSent = true;

                List<NetworkPacket> networkPackets = entry.getValue();

                assertEquals(4, networkPackets.size());

                for (NetworkPacket networkPacket : networkPackets) {

                    long timestamp = networkPacket.getTimestamp(); // timestamp of operation
                    byte[] data = networkPacket.getBytes(); // captured traffic

                    assertTrue(timestamp >= prevTimeStamp);
                    prevTimeStamp = timestamp;

                    assertEquals(nextPacketMustBeSent, networkPacket.isSent());

                    if (nextPacketMustBeSent) {
                        assertArrayEquals(REQUEST, data);
                    } else {
                        assertArrayEquals(RESPONSE, data);
                    }

                    nextPacketMustBeSent = !nextPacketMustBeSent;

                }

            }

        }

    }

    @Test
    @Stories({"issues/400", "issues/401"})
    public void testTrafficCaptureDisabled() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(false).build())) {

            assertTrue(spy.getNetworkTraffic().isEmpty());

        }

    }

    @Test
    @Stories({"issues/411"})
    public void testCaptureInputStream() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            try {
                Socket socket = new Socket(localhost, echoServerRule.getBoundPort());
                socket.setReuseAddress(true);

                assertTrue(socket.isConnected());

                OutputStream outputStream = socket.getOutputStream();
                outputStream.write(REQUEST);
                outputStream.flush();
                socket.shutdownOutput();

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                InputStream inputStream = socket.getInputStream();

                {
                    byte[] fourBytesBuff = new byte[4];
                    int numRead = inputStream.read(fourBytesBuff);
                    assertTrue(numRead > 1);
                    baos.write(fourBytesBuff, 0, numRead);
                }

                {
                    byte[] fourBytesBuff = new byte[4];
                    int numRead = inputStream.read(fourBytesBuff, 1, 2);
                    assertTrue(numRead > 1);
                    baos.write(fourBytesBuff, 1, numRead);
                }

                int read;
                while ((read = inputStream.read()) != -1) {
                    baos.write(read);
                }
                socket.shutdownInput();

                echoServerRule.joinThreads();

                assertArrayEquals(REQUEST, echoServerRule.pollReceivedData());
                assertArrayEquals(RESPONSE, baos.toByteArray());
            } catch (IOException e) {
                fail(e.getMessage());
            }

            Map<SocketMetaData, List<NetworkPacket>> networkTraffic = spy.getNetworkTraffic();

            for (Map.Entry<SocketMetaData, List<NetworkPacket>> entry : networkTraffic.entrySet()) {

                SocketMetaData socketMetaData = entry.getKey();

                Protocol protocol = socketMetaData.getProtocol(); // say TCP
                String hostName = socketMetaData.getAddress().getHostName(); // say "hostname.acme.com"
                int port = socketMetaData.getAddress().getPort(); // say 443

                assertEquals(Protocol.TCP, protocol);
                assertEquals(localhost.getHostName(), hostName);
                assertEquals(echoServerRule.getBoundPort(), port);

                String stackTrace = socketMetaData.getStackTrace();// optional stacktrace for operation as a String
                ThreadMetaData threadMetaData = socketMetaData.getThreadMetaData();// information about thread which performed the operation

                assertNull(stackTrace);
                assertNull(threadMetaData);

                boolean nextPacketMustBeSent = true;

                List<NetworkPacket> networkPackets = entry.getValue();

                assertEquals(2, networkPackets.size());

                for (NetworkPacket networkPacket : networkPackets) {

                    long timestamp = networkPacket.getTimestamp(); // timestamp of operation
                    byte[] data = networkPacket.getBytes(); // captured traffic

                    assertTrue(timestamp >= prevTimeStamp);
                    prevTimeStamp = timestamp;

                    assertEquals(nextPacketMustBeSent, networkPacket.isSent());

                    if (nextPacketMustBeSent) {
                        assertArrayEquals(REQUEST, data);
                    } else {
                        assertArrayEquals(RESPONSE, data);
                    }

                    nextPacketMustBeSent = !nextPacketMustBeSent;

                }

            }

        }

    }

    @Test
    @Stories({"issues/411"})
    public void testCaptureInputStream_SendUrgentData() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            Socket socket = new Socket(localhost, echoServerRule.getBoundPort());
            socket.setReuseAddress(true);

            socket.setOOBInline(true);
            assertTrue(socket.getOOBInline());

            assertTrue(socket.isConnected());

            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(REQUEST, 0, REQUEST.length - 1);
            outputStream.flush();
            socket.sendUrgentData(REQUEST[REQUEST.length - 1]);
            outputStream.flush();

            // On MacOS send urgent data test fails without busy loop on some reason
            for (int i = 0; i < 10_000 && echoServerRule.getBytesReceived() < REQUEST.length; i++) {
                Thread.sleep(1);
                if (9999 == i) {
                    System.err.println("Echo server hasn't received urgent data within 10 seconds");
                }
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            InputStream inputStream = socket.getInputStream();
            int read;
            while ((read = inputStream.read()) != -1) {
                baos.write(read);
            }

            inputStream.close();

            // On MacOS send urgent data test fails without busy loop on some reason
            for (int i = 0; i < 10_000 && echoServerRule.getBytesReceived() < REQUEST.length; i++) {
                Thread.sleep(1);
                if (9999 == i) {
                    System.err.println("Echo server hasn't received urgent data within 20 seconds");<commit_msg>issues/411 urgent data on mac - await for bytes received on EchoServer<commit_after>package io.sniffy.socket;

import io.sniffy.Sniffy;
import io.sniffy.Spy;
import io.sniffy.SpyConfiguration;
import io.sniffy.ThreadMetaData;
import io.sniffy.configuration.SniffyConfiguration;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Stories;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.*;

public class CaptureTrafficTest extends BaseSocketTest {

    @Test
    @Stories({"issues/400", "issues/401"})
    public void testTrafficCapture() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            performSocketOperation();

            Thread thread = new Thread(this::performSocketOperation);
            thread.start();
            thread.join();

            Map<SocketMetaData, List<NetworkPacket>> networkTraffic = spy.getNetworkTraffic();

            for (Map.Entry<SocketMetaData, List<NetworkPacket>> entry : networkTraffic.entrySet()) {

                SocketMetaData socketMetaData = entry.getKey();

                Protocol protocol = socketMetaData.getProtocol(); // say TCP
                String hostName = socketMetaData.getAddress().getHostName(); // say "hostname.acme.com"
                int port = socketMetaData.getAddress().getPort(); // say 443

                assertEquals(Protocol.TCP, protocol);
                assertEquals(localhost.getHostName(), hostName);
                assertEquals(echoServerRule.getBoundPort(), port);

                String stackTrace = socketMetaData.getStackTrace();// optional stacktrace for operation as a String
                ThreadMetaData threadMetaData = socketMetaData.getThreadMetaData();// information about thread which performed the operation

                assertNull(stackTrace);
                assertNull(threadMetaData);

                boolean nextPacketMustBeSent = true;

                List<NetworkPacket> networkPackets = entry.getValue();

                assertEquals(4, networkPackets.size());

                for (NetworkPacket networkPacket : networkPackets) {

                    long timestamp = networkPacket.getTimestamp(); // timestamp of operation
                    byte[] data = networkPacket.getBytes(); // captured traffic

                    assertTrue(timestamp >= prevTimeStamp);
                    prevTimeStamp = timestamp;

                    assertEquals(nextPacketMustBeSent, networkPacket.isSent());

                    if (nextPacketMustBeSent) {
                        assertArrayEquals(REQUEST, data);
                    } else {
                        assertArrayEquals(RESPONSE, data);
                    }

                    nextPacketMustBeSent = !nextPacketMustBeSent;

                }

            }

        }

    }

    @Test
    @Stories({"issues/400", "issues/401"})
    public void testTrafficCaptureDisabled() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(false).build())) {

            assertTrue(spy.getNetworkTraffic().isEmpty());

        }

    }

    @Test
    @Stories({"issues/411"})
    public void testCaptureInputStream() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            try {
                Socket socket = new Socket(localhost, echoServerRule.getBoundPort());
                socket.setReuseAddress(true);

                assertTrue(socket.isConnected());

                OutputStream outputStream = socket.getOutputStream();
                outputStream.write(REQUEST);
                outputStream.flush();
                socket.shutdownOutput();

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                InputStream inputStream = socket.getInputStream();

                {
                    byte[] fourBytesBuff = new byte[4];
                    int numRead = inputStream.read(fourBytesBuff);
                    assertTrue(numRead > 1);
                    baos.write(fourBytesBuff, 0, numRead);
                }

                {
                    byte[] fourBytesBuff = new byte[4];
                    int numRead = inputStream.read(fourBytesBuff, 1, 2);
                    assertTrue(numRead > 1);
                    baos.write(fourBytesBuff, 1, numRead);
                }

                int read;
                while ((read = inputStream.read()) != -1) {
                    baos.write(read);
                }
                socket.shutdownInput();

                echoServerRule.joinThreads();

                assertArrayEquals(REQUEST, echoServerRule.pollReceivedData());
                assertArrayEquals(RESPONSE, baos.toByteArray());
            } catch (IOException e) {
                fail(e.getMessage());
            }

            Map<SocketMetaData, List<NetworkPacket>> networkTraffic = spy.getNetworkTraffic();

            for (Map.Entry<SocketMetaData, List<NetworkPacket>> entry : networkTraffic.entrySet()) {

                SocketMetaData socketMetaData = entry.getKey();

                Protocol protocol = socketMetaData.getProtocol(); // say TCP
                String hostName = socketMetaData.getAddress().getHostName(); // say "hostname.acme.com"
                int port = socketMetaData.getAddress().getPort(); // say 443

                assertEquals(Protocol.TCP, protocol);
                assertEquals(localhost.getHostName(), hostName);
                assertEquals(echoServerRule.getBoundPort(), port);

                String stackTrace = socketMetaData.getStackTrace();// optional stacktrace for operation as a String
                ThreadMetaData threadMetaData = socketMetaData.getThreadMetaData();// information about thread which performed the operation

                assertNull(stackTrace);
                assertNull(threadMetaData);

                boolean nextPacketMustBeSent = true;

                List<NetworkPacket> networkPackets = entry.getValue();

                assertEquals(2, networkPackets.size());

                for (NetworkPacket networkPacket : networkPackets) {

                    long timestamp = networkPacket.getTimestamp(); // timestamp of operation
                    byte[] data = networkPacket.getBytes(); // captured traffic

                    assertTrue(timestamp >= prevTimeStamp);
                    prevTimeStamp = timestamp;

                    assertEquals(nextPacketMustBeSent, networkPacket.isSent());

                    if (nextPacketMustBeSent) {
                        assertArrayEquals(REQUEST, data);
                    } else {
                        assertArrayEquals(RESPONSE, data);
                    }

                    nextPacketMustBeSent = !nextPacketMustBeSent;

                }

            }

        }

    }

    @Test
    @Stories({"issues/411"})
    public void testCaptureInputStream_SendUrgentData() throws Exception {

        SniffyConfiguration.INSTANCE.setMonitorSocket(true);

        long prevTimeStamp = System.currentTimeMillis();

        try (Spy<?> spy = Sniffy.spy(SpyConfiguration.builder().captureNetworkTraffic(true).build())) {

            Socket socket = new Socket(localhost, echoServerRule.getBoundPort());
            socket.setReuseAddress(true);

            socket.setOOBInline(true);
            assertTrue(socket.getOOBInline());

            assertTrue(socket.isConnected());

            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(REQUEST, 0, REQUEST.length - 2);
            outputStream.flush();
            socket.sendUrgentData(REQUEST[REQUEST.length - 2]);
            outputStream.write(REQUEST, REQUEST.length - 1, 1);
            outputStream.flush();

            // On MacOS send urgent data test fails without busy loop on some reason
            for (int i = 0; i < 10_000 && echoServerRule.getBytesReceived() < REQUEST.length; i++) {
                //noinspection BusyWait
                Thread.sleep(1);
                if (9999 == i) {
                    System.err.println("Echo server hasn't received urgent data within 10 seconds");
                }
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            InputStream inputStream = socket.getInputStream();
            int read;
            while ((read = inputStream.read()) != -1) {
                baos.write(read);
            }

            inputStream.close();

            // On MacOS send urgent data test fails without busy loop on some reason
            for (int i = 0; i < 10_000 && echoServerRule.getBytesReceived() < REQUEST.length; i++) {
                //noinspection BusyWait
                Thread.sleep(1);
                if (9999 == i) {
                    System.err.println("Echo server hasn't received urgent data within 20 seconds");
{'fraction_non_alphanumeric': 0.0968486605465185, 'fraction_numerical': 0.007247543887904655, 'mean_word_length': 1.988129611806224, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4670110', 'n_tokens_mistral': 4705, 'n_tokens_neox': 4332, 'n_words': 937}