package io.eguan.nbdsrv.packet; /* * #%L * Project eguan * %% * Copyright (C) 2012 - 2017 Oodrive * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import io.eguan.nbdsrv.packet.DataPushingCmd; import io.eguan.nbdsrv.packet.DataPushingError; import io.eguan.nbdsrv.packet.DataPushingPacket; import io.eguan.nbdsrv.packet.DataPushingReplyPacket; import io.eguan.nbdsrv.packet.ExportFlagsPacket; import io.eguan.nbdsrv.packet.GlobalFlagsPacket; import io.eguan.nbdsrv.packet.InitPacket; import io.eguan.nbdsrv.packet.NbdException; import io.eguan.nbdsrv.packet.OptionCmd; import io.eguan.nbdsrv.packet.OptionPacket; import io.eguan.nbdsrv.packet.OptionReplyCmd; import io.eguan.nbdsrv.packet.OptionReplyPacket; import java.nio.ByteBuffer; import org.junit.Test; public class TestPacket { private static String exportName = "testDevice"; private final static byte[] init = { 0x4e, 0x42, 0x44, 0x4d, 0x41, 0x47, 0x49, 0x43, 0x49, 0x48, 0x41, 0x56, 0x45, 0x4f, 0x50, 0x54, 0x00, 0x01 }; private final static byte[] globalFlags = { 0x00, 0x00, 0x00, 0x01 }; private final static byte[] optionList = { 0x49, 0x48, 0x41, 0x56, 0x45, 0x4f, 0x50, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 }; private final static byte[] replyListWithData = { 0x00, 0x03, -24, -119, 0x04, 0x55, 0x65, -87, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0A, 0x74, 0x65, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65 }; private final static byte[] replyListAck = { 0x00, 0x03, -24, -119, 0x04, 0x55, 0x65, -87, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; private final static byte[] replyList = { 0x00, 0x03, -24, -119, 0x04, 0x55, 0x65, -87, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e }; private final static byte[] replyListData = { 0x00, 0x00, 0x00, 0x0A, 0x74, 0x65, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65 }; private final static byte[] optionExportName = { 0x49, 0x48, 0x41, 0x56, 0x45, 0x4f, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A }; private final static byte[] name = { 0x74, 0x65, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65 }; private final static byte[] exportFlags = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; private final static byte[] dataPushingWrite = { 0x25, 0x60, -107, 0x13, 0x00, 0x00, 0x00, 0x01, 0x07, -80, 0x07, 0x5b, -4, -117, -7, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 }; private final static byte[] dataPushingRead = { 0x25, 0x60, -107, 0x13, 0x00, 0x00, 0x00, 0x00, 0x11, 0x36, 0x0e, 0x75, -24, 0x59, 0x09, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 }; private final static byte[] dataPushingReplyWrite = { 0x67, 0x44, 0x66, -104, 0x00, 0x00, 0x00, 0x00, 0x07, -80, 0x07, 0x5b, -4, -117, -7, 0x23 }; private final static byte[] dataPushingReplyRead = { 0x67, 0x44, 0x66, -104, 0x00, 0x00, 0x00, 0x00, 0x11, 0x36, 0x0e, 0x75, -24, 0x59, 0x09, 0x2b }; @Test public void testInitPacketSerialize() { final InitPacket packet = new InitPacket(InitPacket.MAGIC_STR, InitPacket.MAGIC, 0x01); final ByteBuffer actual = InitPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(init); assertEquals(expected, actual); InitPacket.release(actual); } @Test public void testInitPacketDeserialize() throws NbdException { final InitPacket expected = new InitPacket(InitPacket.MAGIC_STR, InitPacket.MAGIC, 0x01); final InitPacket actual = InitPacket.deserialize(ByteBuffer.wrap(init)); assertEquals(expected.getMagicStr(), actual.getMagicStr()); assertEquals(expected.getMagic(), actual.getMagic()); assertEquals(expected.getGlobalFlags(), actual.getGlobalFlags()); } @Test public void testGlobalFlagsSerialize() { final long flags = GlobalFlagsPacket.NBD_FLAG_FIXED_NEWSTYLE; final ByteBuffer actual = GlobalFlagsPacket.serialize(flags); final ByteBuffer expected = ByteBuffer.wrap(globalFlags); assertEquals(expected, actual); GlobalFlagsPacket.release(actual); } @Test public void testGlobalFlagsDeserialize() throws NbdException { final long expected = GlobalFlagsPacket.NBD_FLAG_FIXED_NEWSTYLE; final long actual = GlobalFlagsPacket.deserialize(ByteBuffer.wrap(globalFlags)); assertEquals(expected, actual); assertTrue(GlobalFlagsPacket.checkNewStyle(actual)); } @Test public void testOptionPacketSerialize() { // List { final OptionPacket packet = new OptionPacket(OptionPacket.MAGIC, OptionCmd.NBD_OPT_LIST, 0); final ByteBuffer[] actuals = OptionPacket.serialize(packet, null); final ByteBuffer expected = ByteBuffer.wrap(optionList); assertEquals(expected, actuals[0]); OptionPacket.release(actuals); } // Export Name { final OptionPacket packet = new OptionPacket(OptionPacket.MAGIC, OptionCmd.NBD_OPT_EXPORT_NAME, exportName.length()); final ByteBuffer[] actuals = OptionPacket.serialize(packet, exportName); final ByteBuffer[] expected = { ByteBuffer.wrap(optionExportName), ByteBuffer.wrap(name) }; assertEquals(expected[0], actuals[0]); assertEquals(expected[1], actuals[1]); OptionPacket.release(actuals); } } @Test public void testOptionPacketDeserialize() throws NbdException { // List { final OptionPacket expected = new OptionPacket(OptionPacket.MAGIC, OptionCmd.NBD_OPT_LIST, 0); final ByteBuffer expectedHeader = ByteBuffer.wrap(optionList); final OptionPacket actual = OptionPacket.deserialize(expectedHeader); assertEquals(expected.getMagicNumber(), actual.getMagicNumber()); assertEquals(expected.getOptionCode(), actual.getOptionCode()); assertEquals(expected.getSize(), actual.getSize()); } // Export Name { final OptionPacket expected = new OptionPacket(OptionPacket.MAGIC, OptionCmd.NBD_OPT_EXPORT_NAME, exportName.length()); // Deserialize header final ByteBuffer expectedHeader = ByteBuffer.wrap(optionExportName); final OptionPacket actual = OptionPacket.deserialize(expectedHeader); assertEquals(expected.getMagicNumber(), actual.getMagicNumber()); assertEquals(expected.getOptionCode(), actual.getOptionCode()); assertEquals(expected.getSize(), actual.getSize()); // Deserialize data final ByteBuffer expectedData = ByteBuffer.wrap(name); assertEquals(exportName, OptionPacket.getData(expectedData)); } } @Test public void testOptionReplyPacketSerialize() { // NBD_REP_SERVER { final OptionReplyPacket packet = new OptionReplyPacket(OptionReplyPacket.MAGIC, OptionCmd.NBD_OPT_LIST, OptionReplyCmd.NBD_REP_SERVER); final String[] data = { exportName }; // Serialize header + data final ByteBuffer[] actuals = OptionReplyPacket.serializeMultiple(packet, data); final ByteBuffer expectedHeader = ByteBuffer.wrap(replyListWithData); assertEquals(expectedHeader, actuals[0]); OptionReplyPacket.release(actuals); } // NBD_REP_ACK { final OptionReplyPacket packet = new OptionReplyPacket(OptionReplyPacket.MAGIC, OptionCmd.NBD_OPT_LIST, OptionReplyCmd.NBD_REP_ACK); final ByteBuffer expected = ByteBuffer.wrap(replyListAck); // Serialize header + data (empty) final ByteBuffer actual = OptionReplyPacket.serialize(packet, ""); assertEquals(expected, actual); OptionReplyPacket.release(actual); } } @Test public void testOptionReplyPacketDeserialize() { // NBD_REP_SERVER { final OptionReplyPacket expected = new OptionReplyPacket(OptionReplyPacket.MAGIC, OptionCmd.NBD_OPT_LIST, OptionReplyCmd.NBD_REP_SERVER); // Set manually data size (is done in serialize) expected.setDataSize(exportName.length() + 4); // Deserialize header final ByteBuffer expectedHeader = ByteBuffer.wrap(replyList); final OptionReplyPacket actual = OptionReplyPacket.deserialize(expectedHeader); assertEquals(expected.getMagic(), actual.getMagic()); assertEquals(expected.getOptionCmd(), actual.getOptionCmd()); assertEquals(expected.getReplyCmd(), actual.getReplyCmd()); assertEquals(expected.getDataSize(), actual.getDataSize()); // Deserialize data final ByteBuffer expectedData = ByteBuffer.wrap(replyListData); assertEquals(exportName, OptionReplyPacket.getData(expectedData, expected)[0]); } // NBD_REP_ACK { final OptionReplyPacket expected = new OptionReplyPacket(OptionReplyPacket.MAGIC, OptionCmd.NBD_OPT_LIST, OptionReplyCmd.NBD_REP_ACK); final ByteBuffer expectedHeader = ByteBuffer.wrap(replyListAck); final OptionReplyPacket actual = OptionReplyPacket.deserialize(expectedHeader); assertEquals(expected.getMagic(), actual.getMagic()); assertEquals(expected.getOptionCmd(), actual.getOptionCmd()); assertEquals(expected.getReplyCmd(), actual.getReplyCmd()); assertEquals(expected.getDataSize(), actual.getDataSize()); } } @Test public void testExportFlagsPacketSerialize() { final int flags = ExportFlagsPacket.NBD_FLAG_HAS_FLAGS; final ExportFlagsPacket packet = new ExportFlagsPacket(0x200000000L, flags); final ByteBuffer actual = ExportFlagsPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(exportFlags); assertEquals(expected, actual); ExportFlagsPacket.release(actual); } @Test public void testExportFlagsPacketDeserialize() { final int flags = ExportFlagsPacket.NBD_FLAG_HAS_FLAGS; final ExportFlagsPacket expected = new ExportFlagsPacket(0x200000000L, flags); final ExportFlagsPacket actual = ExportFlagsPacket.deserialize(ByteBuffer.wrap(exportFlags)); assertEquals(expected.getExportSize(), actual.getExportSize()); assertEquals(expected.getExportFlags(), actual.getExportFlags()); } @Test public void testDataPushingSerialize() { // read { final DataPushingPacket packet = new DataPushingPacket(DataPushingPacket.MAGIC, DataPushingCmd.NBD_CMD_READ, 0x11360e75e859092bL, 0x00, 0x100000); final ByteBuffer actual = DataPushingPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(dataPushingRead); assertEquals(expected, actual); } // write { final DataPushingPacket packet = new DataPushingPacket(DataPushingPacket.MAGIC, DataPushingCmd.NBD_CMD_WRITE, 0x07b0075bfc8bf923L, 0x00, 0x100000); final ByteBuffer actual = DataPushingPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(dataPushingWrite); assertEquals(expected, actual); } } @Test public void testDataPushingDeserialize() throws NbdException { // read { final DataPushingPacket expected = new DataPushingPacket(DataPushingPacket.MAGIC, DataPushingCmd.NBD_CMD_READ, 0x11360e75e859092bL, 0x00, 0x100000); final DataPushingPacket actual = DataPushingPacket.deserialize(ByteBuffer.wrap(dataPushingRead)); assertEquals(expected.getFrom(), actual.getFrom()); assertEquals(expected.getHandle(), actual.getHandle()); assertEquals(expected.getLen(), actual.getLen()); assertEquals(expected.getMagic(), actual.getMagic()); assertEquals(expected.getType(), actual.getType()); } // write { final DataPushingPacket expected = new DataPushingPacket(DataPushingPacket.MAGIC, DataPushingCmd.NBD_CMD_WRITE, 0x07b0075bfc8bf923L, 0x00, 0x100000); final DataPushingPacket actual = DataPushingPacket.deserialize(ByteBuffer.wrap(dataPushingWrite)); assertEquals(expected.getFrom(), actual.getFrom()); assertEquals(expected.getHandle(), actual.getHandle()); assertEquals(expected.getLen(), actual.getLen()); assertEquals(expected.getMagic(), actual.getMagic()); assertEquals(expected.getType(), actual.getType()); } } @Test public void testDataPushingReplySerialize() { // read { final DataPushingReplyPacket packet = new DataPushingReplyPacket(DataPushingReplyPacket.MAGIC, DataPushingError.NBD_NO_ERROR, 0x11360e75e859092bL); final ByteBuffer actual = DataPushingReplyPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(dataPushingReplyRead); assertEquals(expected, actual); } // write { final DataPushingReplyPacket packet = new DataPushingReplyPacket(DataPushingReplyPacket.MAGIC, DataPushingError.NBD_NO_ERROR, 0x07b0075bfc8bf923L); final ByteBuffer actual = DataPushingReplyPacket.serialize(packet); final ByteBuffer expected = ByteBuffer.wrap(dataPushingReplyWrite); assertEquals(expected, actual); } } @Test public void testDataPushingReplyDeserialize() throws NbdException { // read { final DataPushingReplyPacket expected = new DataPushingReplyPacket(DataPushingReplyPacket.MAGIC, DataPushingError.NBD_NO_ERROR, 0x11360e75e859092bL); final DataPushingReplyPacket actual = DataPushingReplyPacket.deserialize(ByteBuffer .wrap(dataPushingReplyRead)); assertEquals(expected.getError(), actual.getError()); assertEquals(expected.getHandle(), actual.getHandle()); assertEquals(expected.getMagic(), actual.getMagic()); } // write { final DataPushingReplyPacket expected = new DataPushingReplyPacket(DataPushingReplyPacket.MAGIC, DataPushingError.NBD_NO_ERROR, 0x07b0075bfc8bf923L); final DataPushingReplyPacket actual = DataPushingReplyPacket.deserialize(ByteBuffer .wrap(dataPushingReplyWrite)); assertEquals(expected.getError(), actual.getError()); assertEquals(expected.getHandle(), actual.getHandle()); assertEquals(expected.getMagic(), actual.getMagic()); } } }