Unexpected error when unit testing nested JNA Structure objectsIterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loopHow to unit test abstract classes: extend with stubs?“cannot find symbol method drawImage(java.awt.image.BufferedImage,<nulltype>,int,int)”linux to windows C++ byte arrayJUnit test of the same objectWhy this class should implement java.io.Serializable when I using hibernate?Type mismatch in key from map: expected .. Text, received … LongWritablewhy spill failure happens for Custom Data Type in HadoopFatal error with JNA structureWhen I run The Junit Test Case in Eclispe I am getting The errr
Term used to describe a person who predicts future outcomes
Unlock your Lock
What stops you from using fixed income in developing countries?
Why does Windows store Wi-Fi passwords in a reversible format?
What is the meaning of “these lederhosen are riding up my Bundesliga”?
Is a memoized pure function itself considered pure?
Did anybody find out it was Anakin who blew up the command center?
What is this fighter jet at Weymouth NAS?
According to UK government, Parliament cannot stop a no-deal Brexit: Could this also be used to push through the agreement agreed by Theresa May?
How can I download a file from a host I can only SSH to through another host?
Is this password scheme legit?
Multiple delayed triggers from Massacre Girl interaction
If I said I had $100 when asked, but I actually had $200, would I be lying by omission?
Defending Castle from Zombies
What's the point of fighting monsters in Zelda BoTW?
What is the 3D printer filament (or pellet) most resistant to bending at high heats?
Count the number of shortest paths to n
74S vs 74LS ICs
The term Feed-forward and its meaning?
Why can't UK MPs vote for the Withdrawal Agreement, then renege on the backstop if it comes to that?
Why does matter stay collapsed in the core, following a supernova explosion?
Why is getting a PhD considered "financially irresponsible" by some people?
Why does this London Underground poster from 1924 have a Star of David atop a Christmas tree?
Is there a word or phrase that means "use other people's wifi or Internet service without consent"?
Unexpected error when unit testing nested JNA Structure objects
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loopHow to unit test abstract classes: extend with stubs?“cannot find symbol method drawImage(java.awt.image.BufferedImage,<nulltype>,int,int)”linux to windows C++ byte arrayJUnit test of the same objectWhy this class should implement java.io.Serializable when I using hibernate?Type mismatch in key from map: expected .. Text, received … LongWritablewhy spill failure happens for Custom Data Type in HadoopFatal error with JNA structureWhen I run The Junit Test Case in Eclispe I am getting The errr
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
The following unit test is intended to verify that a nested JNA data structure is properly parsed based on the data that gets passed into the constructor. The unit test properly checks when JNA initializes the 'parent' structure. However, the test fails when testing member variables of a nested structure. I suspect the problem to be that the unit test sets a pointer to a memory location that contains the data for the nested structure. Perhaps the Java Pointer isn't translating one-to-one to how C does it.
I tried placing the WlanBssEntry at the start of WlanBssEntry[] but that didn't provide any different results than how it is currently implemented. When I tried placing it contiguously, I did not call pointerToMem.setPointer(8, ...)
This is the unit test:
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 = 1024;
@Before
public void setUp()
assumeThat(Utils.getPlatform(), equalTo(Platform.WINDOWS));
pWlanBssList = allocateMemory(65536);
initWlanBssEntryMemory(pWlanBssList, OFFSET_TO_FIRST_WLAN_BSS_ENTRY, 50);
initWlanBssListMemory(pWlanBssList, 12, 1, OFFSET_TO_FIRST_WLAN_BSS_ENTRY);
@Test
public void shouldSetTotalSize()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set total size", new WinDef.DWORD(12), subject.dwTotalSize);
@Test
public void shouldSetNumberOfItems()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set number of items", new WinDef.DWORD(1), subject.dwNumberOfItems);
@Test
public void shouldInitWlanBssEntries()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should init WLAN BSS Entries", 1, subject.wlanBssEntries.length);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
@Test
public void shouldInitWlanBssEntriesWhenNoEntriesExist()
pWlanBssList.setInt(4, 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, long offsetToWlanBssEntry)
pointerToMem.setInt(0, dwTotalSize);
pointerToMem.setInt(4, dwNumberOfItems);
pointerToMem.setPointer(8, pointerToMem.share(offsetToWlanBssEntry));
private void initWlanBssEntryMemory(Pointer pointerToMem, long offsetToWlanBssEntry, long uPhyId)
final int PHY_ID_OFFSET = 40;
pointerToMem.setLong(offsetToWlanBssEntry + 0, 3);
pointerToMem.setByte(offsetToWlanBssEntry + 8, (byte)'T');
pointerToMem.setByte(offsetToWlanBssEntry + 9, (byte)'S');
pointerToMem.setByte(offsetToWlanBssEntry + 10, (byte)'T');
pointerToMem.setLong(offsetToWlanBssEntry + PHY_ID_OFFSET, uPhyId);
This is the WlanBssList class which is the highest level structure:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.DWORD;
import java.util.Arrays;
import java.util.List;
public class WlanBssList extends Structure
public DWORD dwTotalSize;
public DWORD dwNumberOfItems;
public WlanBssEntry[] wlanBssEntries;
public static class ByReference extends WlanBssList implements Structure.ByReference
public ByReference()
public ByReference(Pointer p)
super(p);
public WlanBssList()
wlanBssEntries = new WlanBssEntry[1];
public WlanBssList(Pointer p)
super(p);
dwTotalSize = new DWORD(p.getInt(0));
dwNumberOfItems = new DWORD(p.getInt(4));
if(dwNumberOfItems.intValue() > 0)
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];
readField("wlanBssEntries");
else
wlanBssEntries = new WlanBssEntry[0];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dwTotalSize", "dwNumberOfItems", "wlanBssEntries");
And these are the nested structures:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sevensignal.EyeQAgent.Models.InformationElementGetter;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.USHORT;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WlanBssEntry extends Structure implements InformationElementGetter
public DOT11_SSID dot11Ssid;
public ULONG uPhyId;
public DOT11_MAC_ADDRESS dot11Bssid;
public int dot11BssType;
public int dot11BssPhyType;
public LONG lRssi;
public ULONG uLinkQuality;
public boolean bInRegDomain;
public USHORT usBeaconPeriod;
public ULONGLONG ullTimestamp;
public ULONGLONG ullHostTimestamp;
public USHORT usCapabilityInformation;
public ULONG ulChCenterFrequency;
public WlanRateSet wlanRateSet;
public ULONG ulIeOffset;
public ULONG ulIeSize;
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dot11Ssid",
"uPhyId",
"dot11Bssid",
"dot11BssType",
"dot11BssPhyType",
"lRssi",
"uLinkQuality",
"bInRegDomain",
"usBeaconPeriod",
"ullTimestamp",
"ullHostTimestamp",
"usCapabilityInformation",
"ulChCenterFrequency",
"wlanRateSet",
"ulIeOffset",
"ulIeSize");
public byte[] getInformationElement()
return this.getPointer()
.getByteArray(this.ulIeOffset.intValue(), this.ulIeSize.intValue());
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.*;
import java.util.Arrays;
import java.util.List;
public class DOT11_SSID extends Structure
public static class ByReference extends DOT11_SSID implements Structure.ByReference
public static int DOT11_SSID_MAX_LENGTH = 32;
/**
* The length, in bytes, of the ucSSID array.
*/
public ULONG uSSIDLength;
/**
* The SSID. DOT11_SSID_MAX_LENGTH is set to 32.
*/
public byte[] ucSSID;
public DOT11_SSID()
ucSSID = new byte[DOT11_SSID_MAX_LENGTH];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("uSSIDLength", "ucSSID");
@Override
public String toString()
if(uSSIDLength != null)
int ssidArrayLength = uSSIDLength.intValue();
if (ssidArrayLength > DOT11_SSID_MAX_LENGTH)
ssidArrayLength = DOT11_SSID_MAX_LENGTH;
return new String(Arrays.copyOfRange(ucSSID, 0, ssidArrayLength));
else
return "";
The results of the unit test are:
java.lang.AssertionError: should init WLAN BSS Entry data struct
Expected :50
Actual :0
The assertion that fails is:
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
java windows junit jna
|
show 3 more comments
The following unit test is intended to verify that a nested JNA data structure is properly parsed based on the data that gets passed into the constructor. The unit test properly checks when JNA initializes the 'parent' structure. However, the test fails when testing member variables of a nested structure. I suspect the problem to be that the unit test sets a pointer to a memory location that contains the data for the nested structure. Perhaps the Java Pointer isn't translating one-to-one to how C does it.
I tried placing the WlanBssEntry at the start of WlanBssEntry[] but that didn't provide any different results than how it is currently implemented. When I tried placing it contiguously, I did not call pointerToMem.setPointer(8, ...)
This is the unit test:
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 = 1024;
@Before
public void setUp()
assumeThat(Utils.getPlatform(), equalTo(Platform.WINDOWS));
pWlanBssList = allocateMemory(65536);
initWlanBssEntryMemory(pWlanBssList, OFFSET_TO_FIRST_WLAN_BSS_ENTRY, 50);
initWlanBssListMemory(pWlanBssList, 12, 1, OFFSET_TO_FIRST_WLAN_BSS_ENTRY);
@Test
public void shouldSetTotalSize()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set total size", new WinDef.DWORD(12), subject.dwTotalSize);
@Test
public void shouldSetNumberOfItems()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set number of items", new WinDef.DWORD(1), subject.dwNumberOfItems);
@Test
public void shouldInitWlanBssEntries()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should init WLAN BSS Entries", 1, subject.wlanBssEntries.length);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
@Test
public void shouldInitWlanBssEntriesWhenNoEntriesExist()
pWlanBssList.setInt(4, 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, long offsetToWlanBssEntry)
pointerToMem.setInt(0, dwTotalSize);
pointerToMem.setInt(4, dwNumberOfItems);
pointerToMem.setPointer(8, pointerToMem.share(offsetToWlanBssEntry));
private void initWlanBssEntryMemory(Pointer pointerToMem, long offsetToWlanBssEntry, long uPhyId)
final int PHY_ID_OFFSET = 40;
pointerToMem.setLong(offsetToWlanBssEntry + 0, 3);
pointerToMem.setByte(offsetToWlanBssEntry + 8, (byte)'T');
pointerToMem.setByte(offsetToWlanBssEntry + 9, (byte)'S');
pointerToMem.setByte(offsetToWlanBssEntry + 10, (byte)'T');
pointerToMem.setLong(offsetToWlanBssEntry + PHY_ID_OFFSET, uPhyId);
This is the WlanBssList class which is the highest level structure:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.DWORD;
import java.util.Arrays;
import java.util.List;
public class WlanBssList extends Structure
public DWORD dwTotalSize;
public DWORD dwNumberOfItems;
public WlanBssEntry[] wlanBssEntries;
public static class ByReference extends WlanBssList implements Structure.ByReference
public ByReference()
public ByReference(Pointer p)
super(p);
public WlanBssList()
wlanBssEntries = new WlanBssEntry[1];
public WlanBssList(Pointer p)
super(p);
dwTotalSize = new DWORD(p.getInt(0));
dwNumberOfItems = new DWORD(p.getInt(4));
if(dwNumberOfItems.intValue() > 0)
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];
readField("wlanBssEntries");
else
wlanBssEntries = new WlanBssEntry[0];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dwTotalSize", "dwNumberOfItems", "wlanBssEntries");
And these are the nested structures:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sevensignal.EyeQAgent.Models.InformationElementGetter;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.USHORT;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WlanBssEntry extends Structure implements InformationElementGetter
public DOT11_SSID dot11Ssid;
public ULONG uPhyId;
public DOT11_MAC_ADDRESS dot11Bssid;
public int dot11BssType;
public int dot11BssPhyType;
public LONG lRssi;
public ULONG uLinkQuality;
public boolean bInRegDomain;
public USHORT usBeaconPeriod;
public ULONGLONG ullTimestamp;
public ULONGLONG ullHostTimestamp;
public USHORT usCapabilityInformation;
public ULONG ulChCenterFrequency;
public WlanRateSet wlanRateSet;
public ULONG ulIeOffset;
public ULONG ulIeSize;
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dot11Ssid",
"uPhyId",
"dot11Bssid",
"dot11BssType",
"dot11BssPhyType",
"lRssi",
"uLinkQuality",
"bInRegDomain",
"usBeaconPeriod",
"ullTimestamp",
"ullHostTimestamp",
"usCapabilityInformation",
"ulChCenterFrequency",
"wlanRateSet",
"ulIeOffset",
"ulIeSize");
public byte[] getInformationElement()
return this.getPointer()
.getByteArray(this.ulIeOffset.intValue(), this.ulIeSize.intValue());
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.*;
import java.util.Arrays;
import java.util.List;
public class DOT11_SSID extends Structure
public static class ByReference extends DOT11_SSID implements Structure.ByReference
public static int DOT11_SSID_MAX_LENGTH = 32;
/**
* The length, in bytes, of the ucSSID array.
*/
public ULONG uSSIDLength;
/**
* The SSID. DOT11_SSID_MAX_LENGTH is set to 32.
*/
public byte[] ucSSID;
public DOT11_SSID()
ucSSID = new byte[DOT11_SSID_MAX_LENGTH];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("uSSIDLength", "ucSSID");
@Override
public String toString()
if(uSSIDLength != null)
int ssidArrayLength = uSSIDLength.intValue();
if (ssidArrayLength > DOT11_SSID_MAX_LENGTH)
ssidArrayLength = DOT11_SSID_MAX_LENGTH;
return new String(Arrays.copyOfRange(ucSSID, 0, ssidArrayLength));
else
return "";
The results of the unit test are:
java.lang.AssertionError: should init WLAN BSS Entry data struct
Expected :50
Actual :0
The assertion that fails is:
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
java windows junit jna
1
Welcome to Stack Overflow! I'm not sure but think your array initializationwlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];won't work. You should dowlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)
– Daniel Widdis
Mar 27 at 21:06
1
to be more clear, thenew foo[]structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individualfooin the array (non-contiguous native memory which wouldn't work well as an array parameter) or usetoArray()to initialize the structures with contiguous native memory.
– Daniel Widdis
Mar 27 at 21:14
1
JNA iterates over the fields in yourFieldOrderlist, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?
– Daniel Widdis
Mar 28 at 15:39
1
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention oftoArrayhelped and having another sounding board was all it took.
– Aaron Bauman
Mar 28 at 18:15
1
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33
|
show 3 more comments
The following unit test is intended to verify that a nested JNA data structure is properly parsed based on the data that gets passed into the constructor. The unit test properly checks when JNA initializes the 'parent' structure. However, the test fails when testing member variables of a nested structure. I suspect the problem to be that the unit test sets a pointer to a memory location that contains the data for the nested structure. Perhaps the Java Pointer isn't translating one-to-one to how C does it.
I tried placing the WlanBssEntry at the start of WlanBssEntry[] but that didn't provide any different results than how it is currently implemented. When I tried placing it contiguously, I did not call pointerToMem.setPointer(8, ...)
This is the unit test:
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 = 1024;
@Before
public void setUp()
assumeThat(Utils.getPlatform(), equalTo(Platform.WINDOWS));
pWlanBssList = allocateMemory(65536);
initWlanBssEntryMemory(pWlanBssList, OFFSET_TO_FIRST_WLAN_BSS_ENTRY, 50);
initWlanBssListMemory(pWlanBssList, 12, 1, OFFSET_TO_FIRST_WLAN_BSS_ENTRY);
@Test
public void shouldSetTotalSize()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set total size", new WinDef.DWORD(12), subject.dwTotalSize);
@Test
public void shouldSetNumberOfItems()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set number of items", new WinDef.DWORD(1), subject.dwNumberOfItems);
@Test
public void shouldInitWlanBssEntries()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should init WLAN BSS Entries", 1, subject.wlanBssEntries.length);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
@Test
public void shouldInitWlanBssEntriesWhenNoEntriesExist()
pWlanBssList.setInt(4, 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, long offsetToWlanBssEntry)
pointerToMem.setInt(0, dwTotalSize);
pointerToMem.setInt(4, dwNumberOfItems);
pointerToMem.setPointer(8, pointerToMem.share(offsetToWlanBssEntry));
private void initWlanBssEntryMemory(Pointer pointerToMem, long offsetToWlanBssEntry, long uPhyId)
final int PHY_ID_OFFSET = 40;
pointerToMem.setLong(offsetToWlanBssEntry + 0, 3);
pointerToMem.setByte(offsetToWlanBssEntry + 8, (byte)'T');
pointerToMem.setByte(offsetToWlanBssEntry + 9, (byte)'S');
pointerToMem.setByte(offsetToWlanBssEntry + 10, (byte)'T');
pointerToMem.setLong(offsetToWlanBssEntry + PHY_ID_OFFSET, uPhyId);
This is the WlanBssList class which is the highest level structure:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.DWORD;
import java.util.Arrays;
import java.util.List;
public class WlanBssList extends Structure
public DWORD dwTotalSize;
public DWORD dwNumberOfItems;
public WlanBssEntry[] wlanBssEntries;
public static class ByReference extends WlanBssList implements Structure.ByReference
public ByReference()
public ByReference(Pointer p)
super(p);
public WlanBssList()
wlanBssEntries = new WlanBssEntry[1];
public WlanBssList(Pointer p)
super(p);
dwTotalSize = new DWORD(p.getInt(0));
dwNumberOfItems = new DWORD(p.getInt(4));
if(dwNumberOfItems.intValue() > 0)
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];
readField("wlanBssEntries");
else
wlanBssEntries = new WlanBssEntry[0];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dwTotalSize", "dwNumberOfItems", "wlanBssEntries");
And these are the nested structures:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sevensignal.EyeQAgent.Models.InformationElementGetter;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.USHORT;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WlanBssEntry extends Structure implements InformationElementGetter
public DOT11_SSID dot11Ssid;
public ULONG uPhyId;
public DOT11_MAC_ADDRESS dot11Bssid;
public int dot11BssType;
public int dot11BssPhyType;
public LONG lRssi;
public ULONG uLinkQuality;
public boolean bInRegDomain;
public USHORT usBeaconPeriod;
public ULONGLONG ullTimestamp;
public ULONGLONG ullHostTimestamp;
public USHORT usCapabilityInformation;
public ULONG ulChCenterFrequency;
public WlanRateSet wlanRateSet;
public ULONG ulIeOffset;
public ULONG ulIeSize;
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dot11Ssid",
"uPhyId",
"dot11Bssid",
"dot11BssType",
"dot11BssPhyType",
"lRssi",
"uLinkQuality",
"bInRegDomain",
"usBeaconPeriod",
"ullTimestamp",
"ullHostTimestamp",
"usCapabilityInformation",
"ulChCenterFrequency",
"wlanRateSet",
"ulIeOffset",
"ulIeSize");
public byte[] getInformationElement()
return this.getPointer()
.getByteArray(this.ulIeOffset.intValue(), this.ulIeSize.intValue());
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.*;
import java.util.Arrays;
import java.util.List;
public class DOT11_SSID extends Structure
public static class ByReference extends DOT11_SSID implements Structure.ByReference
public static int DOT11_SSID_MAX_LENGTH = 32;
/**
* The length, in bytes, of the ucSSID array.
*/
public ULONG uSSIDLength;
/**
* The SSID. DOT11_SSID_MAX_LENGTH is set to 32.
*/
public byte[] ucSSID;
public DOT11_SSID()
ucSSID = new byte[DOT11_SSID_MAX_LENGTH];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("uSSIDLength", "ucSSID");
@Override
public String toString()
if(uSSIDLength != null)
int ssidArrayLength = uSSIDLength.intValue();
if (ssidArrayLength > DOT11_SSID_MAX_LENGTH)
ssidArrayLength = DOT11_SSID_MAX_LENGTH;
return new String(Arrays.copyOfRange(ucSSID, 0, ssidArrayLength));
else
return "";
The results of the unit test are:
java.lang.AssertionError: should init WLAN BSS Entry data struct
Expected :50
Actual :0
The assertion that fails is:
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
java windows junit jna
The following unit test is intended to verify that a nested JNA data structure is properly parsed based on the data that gets passed into the constructor. The unit test properly checks when JNA initializes the 'parent' structure. However, the test fails when testing member variables of a nested structure. I suspect the problem to be that the unit test sets a pointer to a memory location that contains the data for the nested structure. Perhaps the Java Pointer isn't translating one-to-one to how C does it.
I tried placing the WlanBssEntry at the start of WlanBssEntry[] but that didn't provide any different results than how it is currently implemented. When I tried placing it contiguously, I did not call pointerToMem.setPointer(8, ...)
This is the unit test:
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 = 1024;
@Before
public void setUp()
assumeThat(Utils.getPlatform(), equalTo(Platform.WINDOWS));
pWlanBssList = allocateMemory(65536);
initWlanBssEntryMemory(pWlanBssList, OFFSET_TO_FIRST_WLAN_BSS_ENTRY, 50);
initWlanBssListMemory(pWlanBssList, 12, 1, OFFSET_TO_FIRST_WLAN_BSS_ENTRY);
@Test
public void shouldSetTotalSize()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set total size", new WinDef.DWORD(12), subject.dwTotalSize);
@Test
public void shouldSetNumberOfItems()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should set number of items", new WinDef.DWORD(1), subject.dwNumberOfItems);
@Test
public void shouldInitWlanBssEntries()
WlanBssList subject = new WlanBssList(pWlanBssList);
assertEquals("should init WLAN BSS Entries", 1, subject.wlanBssEntries.length);
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
@Test
public void shouldInitWlanBssEntriesWhenNoEntriesExist()
pWlanBssList.setInt(4, 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, long offsetToWlanBssEntry)
pointerToMem.setInt(0, dwTotalSize);
pointerToMem.setInt(4, dwNumberOfItems);
pointerToMem.setPointer(8, pointerToMem.share(offsetToWlanBssEntry));
private void initWlanBssEntryMemory(Pointer pointerToMem, long offsetToWlanBssEntry, long uPhyId)
final int PHY_ID_OFFSET = 40;
pointerToMem.setLong(offsetToWlanBssEntry + 0, 3);
pointerToMem.setByte(offsetToWlanBssEntry + 8, (byte)'T');
pointerToMem.setByte(offsetToWlanBssEntry + 9, (byte)'S');
pointerToMem.setByte(offsetToWlanBssEntry + 10, (byte)'T');
pointerToMem.setLong(offsetToWlanBssEntry + PHY_ID_OFFSET, uPhyId);
This is the WlanBssList class which is the highest level structure:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.DWORD;
import java.util.Arrays;
import java.util.List;
public class WlanBssList extends Structure
public DWORD dwTotalSize;
public DWORD dwNumberOfItems;
public WlanBssEntry[] wlanBssEntries;
public static class ByReference extends WlanBssList implements Structure.ByReference
public ByReference()
public ByReference(Pointer p)
super(p);
public WlanBssList()
wlanBssEntries = new WlanBssEntry[1];
public WlanBssList(Pointer p)
super(p);
dwTotalSize = new DWORD(p.getInt(0));
dwNumberOfItems = new DWORD(p.getInt(4));
if(dwNumberOfItems.intValue() > 0)
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];
readField("wlanBssEntries");
else
wlanBssEntries = new WlanBssEntry[0];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dwTotalSize", "dwNumberOfItems", "wlanBssEntries");
And these are the nested structures:
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sevensignal.EyeQAgent.Models.InformationElementGetter;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.USHORT;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WlanBssEntry extends Structure implements InformationElementGetter
public DOT11_SSID dot11Ssid;
public ULONG uPhyId;
public DOT11_MAC_ADDRESS dot11Bssid;
public int dot11BssType;
public int dot11BssPhyType;
public LONG lRssi;
public ULONG uLinkQuality;
public boolean bInRegDomain;
public USHORT usBeaconPeriod;
public ULONGLONG ullTimestamp;
public ULONGLONG ullHostTimestamp;
public USHORT usCapabilityInformation;
public ULONG ulChCenterFrequency;
public WlanRateSet wlanRateSet;
public ULONG ulIeOffset;
public ULONG ulIeSize;
@Override
protected List<String> getFieldOrder()
return Arrays.asList("dot11Ssid",
"uPhyId",
"dot11Bssid",
"dot11BssType",
"dot11BssPhyType",
"lRssi",
"uLinkQuality",
"bInRegDomain",
"usBeaconPeriod",
"ullTimestamp",
"ullHostTimestamp",
"usCapabilityInformation",
"ulChCenterFrequency",
"wlanRateSet",
"ulIeOffset",
"ulIeSize");
public byte[] getInformationElement()
return this.getPointer()
.getByteArray(this.ulIeOffset.intValue(), this.ulIeSize.intValue());
package com.sevensignal.EyeQAgent.Util.win32.struct;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.*;
import java.util.Arrays;
import java.util.List;
public class DOT11_SSID extends Structure
public static class ByReference extends DOT11_SSID implements Structure.ByReference
public static int DOT11_SSID_MAX_LENGTH = 32;
/**
* The length, in bytes, of the ucSSID array.
*/
public ULONG uSSIDLength;
/**
* The SSID. DOT11_SSID_MAX_LENGTH is set to 32.
*/
public byte[] ucSSID;
public DOT11_SSID()
ucSSID = new byte[DOT11_SSID_MAX_LENGTH];
@Override
protected List<String> getFieldOrder()
return Arrays.asList("uSSIDLength", "ucSSID");
@Override
public String toString()
if(uSSIDLength != null)
int ssidArrayLength = uSSIDLength.intValue();
if (ssidArrayLength > DOT11_SSID_MAX_LENGTH)
ssidArrayLength = DOT11_SSID_MAX_LENGTH;
return new String(Arrays.copyOfRange(ucSSID, 0, ssidArrayLength));
else
return "";
The results of the unit test are:
java.lang.AssertionError: should init WLAN BSS Entry data struct
Expected :50
Actual :0
The assertion that fails is:
assertEquals("should init WLAN BSS Entry data struct", new WinDef.LONG(50), subject.wlanBssEntries[0].uPhyId);
java windows junit jna
java windows junit jna
asked Mar 27 at 20:27
Aaron BaumanAaron Bauman
163 bronze badges
163 bronze badges
1
Welcome to Stack Overflow! I'm not sure but think your array initializationwlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];won't work. You should dowlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)
– Daniel Widdis
Mar 27 at 21:06
1
to be more clear, thenew foo[]structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individualfooin the array (non-contiguous native memory which wouldn't work well as an array parameter) or usetoArray()to initialize the structures with contiguous native memory.
– Daniel Widdis
Mar 27 at 21:14
1
JNA iterates over the fields in yourFieldOrderlist, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?
– Daniel Widdis
Mar 28 at 15:39
1
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention oftoArrayhelped and having another sounding board was all it took.
– Aaron Bauman
Mar 28 at 18:15
1
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33
|
show 3 more comments
1
Welcome to Stack Overflow! I'm not sure but think your array initializationwlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];won't work. You should dowlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)
– Daniel Widdis
Mar 27 at 21:06
1
to be more clear, thenew foo[]structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individualfooin the array (non-contiguous native memory which wouldn't work well as an array parameter) or usetoArray()to initialize the structures with contiguous native memory.
– Daniel Widdis
Mar 27 at 21:14
1
JNA iterates over the fields in yourFieldOrderlist, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?
– Daniel Widdis
Mar 28 at 15:39
1
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention oftoArrayhelped and having another sounding board was all it took.
– Aaron Bauman
Mar 28 at 18:15
1
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33
1
1
Welcome to Stack Overflow! I'm not sure but think your array initialization
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()]; won't work. You should do wlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)– Daniel Widdis
Mar 27 at 21:06
Welcome to Stack Overflow! I'm not sure but think your array initialization
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()]; won't work. You should do wlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)– Daniel Widdis
Mar 27 at 21:06
1
1
to be more clear, the
new foo[] structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individual foo in the array (non-contiguous native memory which wouldn't work well as an array parameter) or use toArray() to initialize the structures with contiguous native memory.– Daniel Widdis
Mar 27 at 21:14
to be more clear, the
new foo[] structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individual foo in the array (non-contiguous native memory which wouldn't work well as an array parameter) or use toArray() to initialize the structures with contiguous native memory.– Daniel Widdis
Mar 27 at 21:14
1
1
JNA iterates over the fields in your
FieldOrder list, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?– Daniel Widdis
Mar 28 at 15:39
JNA iterates over the fields in your
FieldOrder list, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?– Daniel Widdis
Mar 28 at 15:39
1
1
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention of
toArray helped and having another sounding board was all it took.– Aaron Bauman
Mar 28 at 18:15
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention of
toArray helped and having another sounding board was all it took.– Aaron Bauman
Mar 28 at 18:15
1
1
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33
|
show 3 more comments
1 Answer
1
active
oldest
votes
I fixed the failing unit test. There were 2 problems when the data was initialized in the allocated memory.
First of all, the offset into the uPhyId was off by 4 because I thought the length field of the dot11Ssid was 8 rather than 4.
Secondly, the memory for the first WlanBssEntry is located at an offset of 8 into the WlanBssList structure.
Lastly, I changed how wlanBssEntries gets initialized to guarantee that the array of WlanBssEntry instances appear contiguously in memory. My unit tests passed even without this change. But per @Daniel Widdis recommendations plus some online documentation I figured it's best to follow recommended procedures. It gets initialized as follows:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Here is the code for the passing unit test:
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);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55385907%2funexpected-error-when-unit-testing-nested-jna-structure-objects%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I fixed the failing unit test. There were 2 problems when the data was initialized in the allocated memory.
First of all, the offset into the uPhyId was off by 4 because I thought the length field of the dot11Ssid was 8 rather than 4.
Secondly, the memory for the first WlanBssEntry is located at an offset of 8 into the WlanBssList structure.
Lastly, I changed how wlanBssEntries gets initialized to guarantee that the array of WlanBssEntry instances appear contiguously in memory. My unit tests passed even without this change. But per @Daniel Widdis recommendations plus some online documentation I figured it's best to follow recommended procedures. It gets initialized as follows:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Here is the code for the passing unit test:
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);
add a comment |
I fixed the failing unit test. There were 2 problems when the data was initialized in the allocated memory.
First of all, the offset into the uPhyId was off by 4 because I thought the length field of the dot11Ssid was 8 rather than 4.
Secondly, the memory for the first WlanBssEntry is located at an offset of 8 into the WlanBssList structure.
Lastly, I changed how wlanBssEntries gets initialized to guarantee that the array of WlanBssEntry instances appear contiguously in memory. My unit tests passed even without this change. But per @Daniel Widdis recommendations plus some online documentation I figured it's best to follow recommended procedures. It gets initialized as follows:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Here is the code for the passing unit test:
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);
add a comment |
I fixed the failing unit test. There were 2 problems when the data was initialized in the allocated memory.
First of all, the offset into the uPhyId was off by 4 because I thought the length field of the dot11Ssid was 8 rather than 4.
Secondly, the memory for the first WlanBssEntry is located at an offset of 8 into the WlanBssList structure.
Lastly, I changed how wlanBssEntries gets initialized to guarantee that the array of WlanBssEntry instances appear contiguously in memory. My unit tests passed even without this change. But per @Daniel Widdis recommendations plus some online documentation I figured it's best to follow recommended procedures. It gets initialized as follows:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Here is the code for the passing unit test:
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);
I fixed the failing unit test. There were 2 problems when the data was initialized in the allocated memory.
First of all, the offset into the uPhyId was off by 4 because I thought the length field of the dot11Ssid was 8 rather than 4.
Secondly, the memory for the first WlanBssEntry is located at an offset of 8 into the WlanBssList structure.
Lastly, I changed how wlanBssEntries gets initialized to guarantee that the array of WlanBssEntry instances appear contiguously in memory. My unit tests passed even without this change. But per @Daniel Widdis recommendations plus some online documentation I figured it's best to follow recommended procedures. It gets initialized as follows:
wlanBssEntries = (WlanBssEntry[])(new WlanBssEntry()).toArray(dwNumberOfItems.intValue());
Here is the code for the passing unit test:
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);
answered Mar 28 at 20:48
Aaron BaumanAaron Bauman
163 bronze badges
163 bronze badges
add a comment |
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55385907%2funexpected-error-when-unit-testing-nested-jna-structure-objects%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Welcome to Stack Overflow! I'm not sure but think your array initialization
wlanBssEntries = new WlanBssEntry[dwNumberOfItems.intValue()];won't work. You should dowlanBssEntries = (new WlanBssEntry()).toArray(dwNumberOfItems.intValue());. (Also JNA doesn't support 0 length arrays so the second part of your conditional is impossible: always initialize with at least 1 element.)– Daniel Widdis
Mar 27 at 21:06
1
to be more clear, the
new foo[]structure array only works on the Java side and does not initialize the structure object. You would have to initialize every individualfooin the array (non-contiguous native memory which wouldn't work well as an array parameter) or usetoArray()to initialize the structures with contiguous native memory.– Daniel Widdis
Mar 27 at 21:14
1
JNA iterates over the fields in your
FieldOrderlist, using reflection to get the mapped class so it knows their native size so it knows the offset. Are you sure your calculated offsets are correct?– Daniel Widdis
Mar 28 at 15:39
1
I figured it out. I'll post my answer later but wanted to let you know so you don't spend your valuable time. In short, my problem was two fold. First, I did have an offset problem in the data that I was initializing. Second, I didn't place the data I was initializing at the "end" of the WlanBssList (starting at offset 8). Thank you for your help. Your mention of
toArrayhelped and having another sounding board was all it took.– Aaron Bauman
Mar 28 at 18:15
1
Glad you fixed it and that I could help!
– Daniel Widdis
Mar 28 at 18:33