net.epsilony.utils.codec.modbus.handler.ModbusMasterResponseDecoderTest.java Source code

Java tutorial

Introduction

Here is the source code for net.epsilony.utils.codec.modbus.handler.ModbusMasterResponseDecoderTest.java

Source

/*
 *
 * The MIT License (MIT)
 * 
 * Copyright (C) 2013 Man YUAN <epsilon@epsilony.net>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package net.epsilony.utils.codec.modbus.handler;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

import org.junit.Test;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import net.epsilony.utils.codec.modbus.ModbusRegisterType;
import net.epsilony.utils.codec.modbus.Utils;
import net.epsilony.utils.codec.modbus.func.MF;
import net.epsilony.utils.codec.modbus.reqres.ExceptionResponse;
import net.epsilony.utils.codec.modbus.reqres.MissMatchResponse;
import net.epsilony.utils.codec.modbus.reqres.ModbusRequest;
import net.epsilony.utils.codec.modbus.reqres.ModbusResponse;
import net.epsilony.utils.codec.modbus.reqres.ReadBooleanRegistersResponse;
import net.epsilony.utils.codec.modbus.reqres.ReadWordRegistersResponse;
import net.epsilony.utils.codec.modbus.reqres.WriteCoilResponse;
import net.epsilony.utils.codec.modbus.reqres.WriteHoldingResponse;

/**
 * @author <a href="mailto:epsilony@epsilony.net">Man YUAN</a>
 *
 */
public class ModbusMasterResponseDecoderTest {

    Map<Integer, ModbusRequest> requests = new LinkedHashMap<>();

    class TestData {
        ModbusRequest request;
        ModbusResponse response;
        int[] buffer;

        public TestData(ModbusRequest request, ModbusResponse response, int[] buffer) {
            this.request = request;
            this.response = response;
            this.buffer = buffer;
            requests.put(request.getTransectionId(), request);
        }

        public TestData(ModbusRequest request, ModbusResponse response, int[] buffer, boolean addToRecord) {
            this.request = request;
            this.response = response;
            this.buffer = buffer;
            if (addToRecord) {
                requests.put(request.getTransectionId(), request);
            }
        }

        public void writeBuffer(ByteBuf buf) {
            for (int bufferByte : buffer) {
                buf.writeByte(bufferByte);
            }
        }

        public void writeBufferWithCrc(ByteBuf buf) {
            int from = buf.writerIndex();
            writeBuffer(buf);
            buf.writeShort(Utils.crc(buf, from, buf.writerIndex() - from));
        }

    }

    public static ByteBuf createBuf() {
        ByteBuf buf = Unpooled.buffer(1024);
        int randShift = new Random().nextInt(10) + 7;
        buf.writerIndex(randShift);
        buf.readerIndex(randShift);
        return buf;
    }

    @Test
    public void testDecoding() {
        EmbeddedChannel channel = new EmbeddedChannel(new ModbusMasterResponseDecoder(requests::remove));
        TestData[] datas = initTestData();

        ByteBuf buf = createBuf();

        for (TestData data : datas) {
            data.writeBuffer(buf);
        }

        channel.writeInbound(buf);

        for (TestData data : datas) {
            Object decoded = channel.readInbound();
            assertEquals(data.response, decoded);
        }
        assertEquals(null, channel.readInbound());
        assertTrue(buf.refCnt() <= 0);
        assertTrue(requests.isEmpty());
    }

    @Test
    public void testDecodingWithCheckSome() {
        ModbusMasterResponseDecoder decoder = new ModbusMasterResponseDecoder(requests::remove);
        decoder.setWithCheckSum(true);
        EmbeddedChannel channel = new EmbeddedChannel(decoder);
        TestData[] datas = initTestData();

        ByteBuf buf = createBuf();

        for (TestData data : datas) {
            data.writeBufferWithCrc(buf);
        }

        channel.writeInbound(buf);

        for (TestData data : datas) {
            Object decoded = channel.readInbound();
            assertEquals(data.response, decoded);
        }
        assertEquals(null, channel.readInbound());
        assertTrue(buf.refCnt() <= 0);
        assertTrue(requests.isEmpty());
    }

    private TestData[] initTestData() {
        return new TestData[] {
                new TestData(new ModbusRequest(0xAC01, 0xFB, MF.writeRegister(0xFEDC, 0xDAFE)),
                        new WriteHoldingResponse(0xAC01, 0xFB, 0xFEDC, 0xDAFE),
                        new int[] { 0xAC, 0x01, 0x00, 0x00, 0x00, 0x06, 0xFB, 0x06, 0xFE, 0xDC, 0xDA, 0xFE }),
                new TestData(new ModbusRequest(0xAC02, 0xFB, MF.writeRegister(0xFEDC, false)),
                        new WriteCoilResponse(0xAC02, 0xFB, 0xFEDC, false),
                        new int[] { 0xAC, 0x02, 0x00, 0x00, 0x00, 0x06, 0xFB, 0x05, 0xFE, 0xDC, 0x00, 0x00 }),
                new TestData(new ModbusRequest(0xAC03, 0xFB, MF.writeRegister(0xFEDC, true)),
                        new WriteCoilResponse(0xAC03, 0xFB, 0xFEDC, true),
                        new int[] { 0xAC, 0x03, 0x00, 0x00, 0x00, 0x06, 0xFB, 0x05, 0xFE, 0xDC, 0xff, 0x00 }),
                new TestData(new ModbusRequest(0xAB01, 0xFB, MF.readRegisters(ModbusRegisterType.INPUT, 0xFEDC, 3)),
                        new ReadWordRegistersResponse(0xAB01, 0xFB, ModbusRegisterType.INPUT, 0xFEDC,
                                new int[] { 0xFF01, 0xFF02, 0xFF03 }),
                        new int[] { 0xAB, 0x01, 0x00, 0x00, 0x00, 0x09, 0xFB, 0x04, 0x06, 0xff, 0x01, 0xff, 0x02,
                                0xff, 0x03 }),
                new TestData(
                        new ModbusRequest(0xAB02, 0xFB, MF.readRegisters(ModbusRegisterType.HOLDING, 0xFEDC, 3)),
                        new ReadWordRegistersResponse(0xAB02, 0xFB, ModbusRegisterType.HOLDING, 0xFEDC,
                                new int[] { 0xFF01, 0xFF02, 0xFF03 }),
                        new int[] { 0xAB, 0x02, 0x00, 0x00, 0x00, 0x09, 0xFB, 0x03, 0x06, 0xff, 0x01, 0xff, 0x02,
                                0xff, 0x03 }),
                new TestData(
                        new ModbusRequest(0xAB04, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new ReadBooleanRegistersResponse(0xAB04, 0xFB, ModbusRegisterType.DISCRETE_INPUT, 0xFEDC,
                                new boolean[] { true, false, true }),
                        new int[] { 0xAB, 0x04, 0x00, 0x00, 0x00, 0x04, 0xFB, 0x02, 0x01, 0x05 }),
                new TestData(
                        new ModbusRequest(0xAB05, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new ExceptionResponse(0xAB05, 0xFB, 0x82, 0x01),
                        new int[] { 0xAB, 0x05, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x82, 0x01 }),
                new TestData(new ModbusRequest(0xAB03, 0xFB, MF.readRegisters(ModbusRegisterType.COIL, 0xFEDC, 3)),
                        new ReadBooleanRegistersResponse(0xAB03, 0xFB, ModbusRegisterType.COIL, 0xFEDC,
                                new boolean[] { true, false, true }),
                        new int[] { 0xAB, 0x03, 0x00, 0x00, 0x00, 0x04, 0xFB, 0x01, 0x01, 0x05 }),
                new TestData(
                        new ModbusRequest(0xAB06, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new MissMatchResponse(0xAB06),
                        new int[] { 0xAB, 0x06, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x82, 0x01 }, false),
                new TestData(new ModbusRequest(0xAB07, 0xFB, MF.readRegisters(ModbusRegisterType.COIL, 0xFEDC, 3)),
                        new ReadBooleanRegistersResponse(0xAB07, 0xFB, ModbusRegisterType.COIL, 0xFEDC,
                                new boolean[] { true, false, true }),
                        new int[] { 0xAB, 0x07, 0x00, 0x00, 0x00, 0x04, 0xFB, 0x01, 0x01, 0x05 }),
                new TestData(
                        new ModbusRequest(0xAB08, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new ReadBooleanRegistersResponse(0xAB08, 0xFB, ModbusRegisterType.DISCRETE_INPUT, 0xFEDC,
                                new boolean[] { true, false, true }),
                        new int[] { 0xAB, 0x08, 0x00, 0x00, 0x00, 0x04, 0xFB, 0x02, 0x01, 0x05 }),
                new TestData(
                        new ModbusRequest(0xAB09, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new MissMatchResponse(0xAB09),
                        new int[] { 0xAB, 0x09, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x82, 0x01 }, false),
                new TestData(
                        new ModbusRequest(0xAB0a, 0xFB,
                                MF.readRegisters(ModbusRegisterType.DISCRETE_INPUT, 0xFEDC, 3)),
                        new ExceptionResponse(0xAB0a, 0xFB, 0x82, 0x01),
                        new int[] { 0xAB, 0x0a, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x82, 0x01 }), };
    }

}