Package com.javachat.server

Source Code of com.javachat.server.ChatServerTest

package com.javachat.server;

import com.javachat.shared.Command;
import com.javachat.shared.MessageHolder;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.*;

/**
* @author Dmitry Levykin
*/
public class ChatServerTest {
    private static final int PORT = 3000;
    private ChatServer chatServer;
    private final String USER = "Test user";

    ChatServer getChatServer() {
        return chatServer;
    }

    @Before
    public void init() throws IOException {
        chatServer = new ChatServer();
        chatServer.bind(PORT);
    }

    @After
    public void stop() throws IOException {
        chatServer.stop();
    }

    // Канал подключения
    private SocketChannel connect() throws IOException {
        SocketChannel channel = SocketChannel.open();
        channel.connect(new InetSocketAddress("localhost", PORT));
        sendMessage(channel, (Command.LOGIN.getText() + USER).getBytes(ChatServer.CHARSET_NAME));
        readServerMessages(1);
        writeAllServerBuffers();
        readMessage(channel);
        return channel;
    }

    // Отправка сообщения в канал
    private void sendMessage(SocketChannel channel, byte[] messageBytes) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(messageBytes.length + 4);
        buffer.putInt(messageBytes.length);
        buffer.put(messageBytes);
        buffer.flip();
        channel.write(buffer);
    }

    // Чтение сообщения из канала
    private String readMessage(SocketChannel channel) throws IOException {
        return readMessages(channel, 1).get(0);
    }

    // Чтение сообщений из канала
    private List<String> readMessages(SocketChannel channel, int count) throws IOException {
        List<String> retList = new LinkedList<>();
        MessageHolder holder = null;
        ByteBuffer end = null;
        ByteBuffer buffer = ByteBuffer.allocate(10);
        while (count > 0) {
            if (holder == null) {
                holder = new MessageHolder(100, ChatServer.CHARSET_NAME);
            }
            if (end != null) {
                buffer.put(end);
            }
            channel.read(buffer);
            buffer.flip();
            String message = holder.readFromBuffer(buffer);
            if (message != null) {
                retList.add(message);
                holder = null;
                count--;
            }
            if (buffer.hasRemaining()) {
                end = ByteBuffer.allocate(buffer.remaining());
                end.put(buffer);
                end.flip();
            }
            buffer.flip();
        }
        return retList;
    }

    // Запуск сервера без клиентов. Сервер должен быть без активности.
    @Test(timeout = 100)
    public void startServerTest() throws IOException {
        Assert.assertTrue(!chatServer.keyIteration());
    }

    // Заставляем сервер прочитать все входящие сообщения
    private void readServerMessages(int count) throws IOException {
        int countBefore = chatServer.getIncomeMessagesOrCommandsCount();
        while (chatServer.getIncomeMessagesOrCommandsCount() < countBefore + count) {
            chatServer.select();
            chatServer.keyIteration();
        }
    }

    // Заставляем сервер отослать все исходящие сообщения
    private void writeAllServerBuffers() throws IOException {
        do {
            chatServer.select();
        } while (chatServer.keyIteration());
    }

    // Отправка одного сообщения
    @Test(timeout = 100)
    public void sendOneMessagesTest() throws IOException {
        chatServer.setBufferCapacity(10);
        String message = "Hello!";
        SocketChannel channel = connect();
        sendMessage(channel, message.getBytes(ChatServer.CHARSET_NAME));
        readServerMessages(1);
        channel.close();
        Assert.assertEquals(1, chatServer.getClientMessages().size());
        Assert.assertEquals(message, chatServer.getClientMessages().get(0).getText());
    }

    // Отправка одного сообщения между двумя клиентами
    @Test(timeout = 100)
    public void sendOneMessagesC2CTest() throws IOException {
        chatServer.setBufferCapacity(10);
        String message1 = "Hello!";
        SocketChannel channel1 = connect();
        SocketChannel channel2 = connect();
        sendMessage(channel1, message1.getBytes(ChatServer.CHARSET_NAME));
        readServerMessages(1);
        writeAllServerBuffers();
        String message2 = readMessage(channel2);
        channel1.close();
        channel2.close();
        Assert.assertEquals(ChatServer.getUserMessageString(USER, message1), message2);
    }

    // Отправка двух сообщений с буфером превосходящим их совокупный размер
    @Test(timeout = 100)
    public void sendTwoMessagesWithLargeBufferTest() throws IOException {
        chatServer.setBufferCapacity(20);
        String message1 = "Hello!";
        String message2 = "Hi!";
        SocketChannel channel = connect();
        sendMessage(channel,  message1.getBytes(ChatServer.CHARSET_NAME));
        sendMessage(channel,  message2.getBytes(ChatServer.CHARSET_NAME));
        readServerMessages(2);

        channel.close();
        Assert.assertEquals(2, chatServer.getClientMessages().size());
        Assert.assertEquals(message1, chatServer.getClientMessages().get(0).getText());
        Assert.assertEquals(message2, chatServer.getClientMessages().get(1).getText());
    }

    // Отправка двух сообщений с ограниченным буфером
    @Test(timeout = 100)
    public void sendTwoWithSmallBufferTest() throws IOException {
        chatServer.setBufferCapacity(10);
        String message1 = "Hello!";
        String message2 = "Hi!";
        SocketChannel channel = connect();
        sendMessage(channel,  message1.getBytes(ChatServer.CHARSET_NAME));
        sendMessage(channel,  message2.getBytes(ChatServer.CHARSET_NAME));
        readServerMessages(2);
        channel.close();
        Assert.assertEquals(2, chatServer.getClientMessages().size());
        Assert.assertEquals(message1, chatServer.getClientMessages().get(0).getText());
        Assert.assertEquals(message2, chatServer.getClientMessages().get(1).getText());
    }

    // Большое количество сообщений от одного клиента
    @Test(timeout = 300)
    public void sendMessagesTest() throws IOException {
        chatServer.setBufferCapacity(20);
        SocketChannel channel = connect();

        // Accept
        chatServer.select();
        chatServer.keyIteration();

        int sendCount = 1000;
        List<String> sendList = new ArrayList<>(sendCount);

        for (int i = 0; i < sendCount; i++) {
            String message = "Message " + i;
            sendList.add(message);
            sendMessage(channel, message.getBytes(ChatServer.CHARSET_NAME));

            readServerMessages(1);
        }

        channel.close();

        List<ChatMessage> receiveList = chatServer.getClientMessages();
        Assert.assertEquals(sendCount, receiveList.size());
        for (int i = 0; i < sendCount; i++) {
            Assert.assertEquals(sendList.get(i), receiveList.get(i).getText());
        }
    }

    // Одновременное подключение 100 пользователей. Каждый посылает по сообщению.
    @Test(timeout = 1000)
    public void send100Messages() throws IOException {
        chatServer.setBufferCapacity(30);
        int count = 100;
        List<SocketChannel> channelList = new ArrayList<>(count);
        Map<SocketChannel, List<String>> messagesMap = new HashMap<>();

        // Подключение и авторизация
        for (int i = 0; i < count; i++) {
            channelList.add(connect());
            messagesMap.put(channelList.get(i), new ArrayList<String>(count - 1));
        }

        // Отправка
        for (int i = 0; i < count; i++) {
            String message = "Message from " + i;
            sendMessage(channelList.get(i), message.getBytes(ChatServer.CHARSET_NAME));
            readServerMessages(1);
        }

        writeAllServerBuffers();

        // Получение сообщений - самая долгая операция
        Assert.assertEquals(count, chatServer.getClientMessages().size());
        for (SocketChannel channel : channelList) {
            List<String> messageList = readMessages(channel, count - 1);
            Assert.assertEquals(count - 1, messageList.size());
            channel.close();
        }
    }
}
TOP

Related Classes of com.javachat.server.ChatServerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.