Я исправил провал модульного теста. Было 2 проблемы, когда данные были инициализированы в выделенной памяти.
Прежде всего, смещение в uPhyId
было отключено на 4, потому что я думал, что поле длины dot11Ssid
было 8, а не 4.
Во-вторых, память для первого WlanBssEntry
расположена со смещением 8 в структуре WlanBssList
.
Наконец, я изменил способ инициализации wlanBssEntries
, чтобы гарантировать, что массив экземпляров WlanBssEntry
будет непрерывно появляться в памяти. Мои юнит-тесты прошли даже без этого изменения. Но согласно рекомендациям @Daniel Widdis и некоторой онлайн-документации, я решил, что лучше следовать рекомендуемым процедурам. Он инициализируется следующим образом:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Вот код для прохождения модульного теста:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sevensignal.EyeQAgent.Models.Platform;
import com.sevensignal.EyeQAgent.Util.Utils;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeThat;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Utils.class})
public class WlanBssListTest {
Pointer pWlanBssList;
private final static long OFFSET_TO_FIRST_WLAN_BSS_ENTRY = 8;
private final static int PHY_ID_OFFSET = 36;
private final static int WLAN_BSS_ENTRY_LENGTH = 360;
@Before
public void setUp() {
assumeThat(Utils.getPlatform(), equalTo(Platform.WINDOWS));
pWlanBssList = allocateMemory(65536);
}
@Test
public void shouldSetTotalSize() {
initWlanBssListMemory(pWlanBssList, 12, 1);
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set total size", new WinDef.DWORD(12), subject.dwTotalSize);
}
@Test
public void shouldSetNumberOfItems() {
initWlanBssListMemory(pWlanBssList, 12, 1);
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set number of items", new WinDef.DWORD(1), subject.dwNumberOfItems);
}
@Test
public void shouldInitWlanBssEntries() {
initWlanBssListMemory(pWlanBssList, 12, 1);
WlanBssList subject = new WlanBssList(pWlanBssList);
assertArrayEquals("should init SSID entry in WLAN BSS Entry data struct",
new byte[]{
(byte)'I', (byte)'D', (byte)'1', (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
},
subject.wlanBssEntries[0].dot11Ssid.ucSSID);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(51), subject.wlanBssEntries[0].uPhyId);
}
@Test
public void shouldInitTwoWlanBssEntries() {
initWlanBssListMemory(pWlanBssList, 12, 2);
WlanBssList subject = new WlanBssList(pWlanBssList);
assertArrayEquals("should init SSID entry in WLAN BSS Entry data struct",
new byte[]{
(byte)'I', (byte)'D', (byte)'1', (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
},
subject.wlanBssEntries[0].dot11Ssid.ucSSID);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(51), subject.wlanBssEntries[0].uPhyId);
assertArrayEquals("should init SSID entry in WLAN BSS Entry data struct",
new byte[]{
(byte)'I', (byte)'D', (byte)'2', (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
},
subject.wlanBssEntries[1].dot11Ssid.ucSSID);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(0xC2), subject.wlanBssEntries[1].uPhyId);
}
@Test
public void shouldInitWlanBssEntriesWhenNoEntriesExist() {
initWlanBssListMemory(pWlanBssList, 12, 0);
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should init WLAN BSS Entries when no entries exist", 0, subject.wlanBssEntries.length);
}
private Pointer allocateMemory(long size) {
return new Memory(size).share(0);
}
private void initWlanBssListMemory(Pointer pointerToMem, int dwTotalSize, int dwNumberOfItems) {
pointerToMem.setInt(0, dwTotalSize);
pointerToMem.setInt(4, dwNumberOfItems);
initWlanBssEntryMemory(pointerToMem);
}
private void initWlanBssEntryMemory(Pointer pointerToWlanBssEntryMem) {
pointerToWlanBssEntryMem.setLong(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + 0, 3);
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + 4, (byte)'I');
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + 5, (byte)'D');
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + 6, (byte)'1');
pointerToWlanBssEntryMem.setMemory(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + 7, 29, (byte)0);
pointerToWlanBssEntryMem.setLong(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + PHY_ID_OFFSET, 51);
pointerToWlanBssEntryMem.setLong(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + 0, 3);
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + 4, (byte)'I');
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + 5, (byte)'D');
pointerToWlanBssEntryMem.setByte(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + 6, (byte)'2');
pointerToWlanBssEntryMem.setMemory(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + 7, 29, (byte)0);
pointerToWlanBssEntryMem.setLong(OFFSET_TO_FIRST_WLAN_BSS_ENTRY + WLAN_BSS_ENTRY_LENGTH + PHY_ID_OFFSET, 0xC2);
}
}