11/**
2- * Copyright (c) 2015 Digi International Inc.,
2+ * Copyright (c) 2015-2016 Digi International Inc.,
33 * All rights not expressly granted are reserved.
44 *
55 * This Source Code Form is subject to the terms of the Mozilla Public
2424import java .lang .management .ThreadMXBean ;
2525import java .util .ArrayList ;
2626import java .util .HashMap ;
27+ import java .util .concurrent .Executors ;
28+ import java .util .concurrent .ScheduledThreadPoolExecutor ;
2729
2830import org .junit .After ;
2931import org .junit .AfterClass ;
@@ -95,13 +97,19 @@ public class DataReaderTest {
9597
9698 private TestConnectionInterface testCI ;
9799
100+ private ScheduledThreadPoolExecutor mockExecutorService ;
101+
98102 @ Rule
99103 public ExpectedException exception = ExpectedException .none ();
100104
101105 class TestConnectionInterface implements IConnectionInterface {
102106
103- boolean isOpen = false ;
104- boolean alreadyRead = false ;
107+ boolean isOpen = true ;
108+ int counter = 4 ; // Because to read a packet the
109+ // 'connectionInterface.getInputStream()' is called
110+ // 3 times inside the 'while (running)' loop of the
111+ // DataReader 'run' method + 1.
112+ boolean transmissionFinished = false ;
105113
106114 @ Override
107115 public void open () throws InterfaceInUseException ,
@@ -122,10 +130,11 @@ public boolean isOpen() {
122130
123131 @ Override
124132 public InputStream getInputStream () {
125- if (alreadyRead )
126- return null ;
127-
128- return mockInput ;
133+ if (counter > 0 ) {
134+ counter --;
135+ return mockInput ;
136+ }
137+ return null ;
129138 }
130139
131140 @ Override
@@ -168,6 +177,14 @@ public void notifyData() {
168177 this .notify ();
169178 }
170179 }
180+
181+ public void setAlreadyRead () {
182+ counter = 0 ;
183+ }
184+
185+ public boolean isAlreadyRead () {
186+ return counter > 0 ;
187+ }
171188 }
172189
173190 /**
@@ -232,13 +249,19 @@ public XBeePacket answer(InvocationOnMock invocation) throws Throwable {
232249
233250 mockQueue = Mockito .mock (XBeePacketsQueue .class );
234251 PowerMockito .whenNew (XBeePacketsQueue .class ).withNoArguments ().thenReturn (mockQueue );
252+
253+ mockExecutorService = Mockito .mock (ScheduledThreadPoolExecutor .class );
254+ PowerMockito .mockStatic (Executors .class );
255+ Mockito .when (Executors .newScheduledThreadPool (Mockito .anyInt ())).thenReturn (mockExecutorService );
256+ // Executors.newScheduledThreadPool(Math.min(MAXIMUM_PARALLEL_LISTENER_THREADS, dataReceiveListeners.size()));
257+
235258 Mockito .doAnswer (new Answer <Object >() {
236- @ Override
237- public Object answer ( InvocationOnMock invocation ) throws Throwable {
238- testCI .alreadyRead = true ;
259+ public Object answer ( InvocationOnMock invocation ) throws Exception {
260+ (( Runnable ) invocation . getArguments ()[ 0 ]). run ();
261+ testCI .transmissionFinished = true ;
239262 return null ;
240263 }
241- }).when (mockQueue ). addPacket (Mockito .any (XBeePacket .class ));
264+ }).when (mockExecutorService ). execute (Mockito .any (Runnable .class ));
242265 }
243266
244267 /**
@@ -253,16 +276,16 @@ private void waitForInitialization(long threadID) throws InterruptedException {
253276 boolean isWaiting = true ;
254277
255278 while (isWaiting ) {
256- ThreadInfo [] infos = mbean .dumpAllThreads (true , true );
257- for (ThreadInfo threadInfo : infos ) {
258- if (threadInfo .getThreadId () == threadID ) {
259- if (threadInfo .getThreadState () == State .WAITING )
260- isWaiting = false ;
261- else
262- Thread .sleep (50 );
263- break ;
264- }
279+ ThreadInfo threadInfo = mbean .getThreadInfo (threadID );
280+ if (threadInfo == null ) {
281+ Thread .sleep (50 );
282+ continue ;
265283 }
284+
285+ if (threadInfo .getThreadState () == State .WAITING )
286+ isWaiting = false ;
287+ else
288+ Thread .sleep (50 );
266289 }
267290 }
268291
@@ -940,10 +963,10 @@ public final void testDataReaderReceivePacketBadHeaderByte() throws Exception {
940963 Mockito .doAnswer (new Answer <Integer >() {
941964 @ Override
942965 public Integer answer (InvocationOnMock invocation ) throws Throwable {
943- if (testCI .alreadyRead )
966+ if (testCI .isAlreadyRead () )
944967 return null ;
945968
946- testCI .alreadyRead = true ;
969+ testCI .setAlreadyRead () ;
947970 return 0x88 ;
948971 }
949972 }).when (mockInput ).read ();
@@ -977,10 +1000,10 @@ public final void testDataReaderReceivePacketBadPacket() throws Exception {
9771000 Mockito .doAnswer (new Answer <XBeePacket >() {
9781001 @ Override
9791002 public XBeePacket answer (InvocationOnMock invocation ) throws Throwable {
980- if (testCI .alreadyRead )
1003+ if (testCI .isAlreadyRead () )
9811004 return null ;
9821005
983- testCI .alreadyRead = true ;
1006+ testCI .setAlreadyRead () ;
9841007 throw new InvalidPacketException ();
9851008 }
9861009 }).when (mockParser ).parsePacket (Mockito .eq (mockInput ), Mockito .any (OperatingMode .class ));
@@ -1242,7 +1265,7 @@ public final void testDataReaderReceivePacketRX64DataPacket() throws Exception {
12421265
12431266 waitForInitialization (dataReader .getId ());
12441267 testCI .notifyData ();
1245- while (dataReader .isRunning ())
1268+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
12461269 Thread .sleep (30 );
12471270
12481271 // Verify the result.
@@ -1284,7 +1307,7 @@ public final void testDataReaderReceivePacketRX16DataPacket() throws Exception {
12841307
12851308 waitForInitialization (dataReader .getId ());
12861309 testCI .notifyData ();
1287- while (dataReader .isRunning ())
1310+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
12881311 Thread .sleep (30 );
12891312
12901313 // Verify the result.
@@ -1326,7 +1349,7 @@ public final void testDataReaderReceivePacketRXDataPacket() throws Exception {
13261349
13271350 waitForInitialization (dataReader .getId ());
13281351 testCI .notifyData ();
1329- while (dataReader .isRunning ())
1352+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
13301353 Thread .sleep (30 );
13311354
13321355 // Verify the result.
@@ -1368,7 +1391,7 @@ public final void testDataReaderReceivePacketRXIO64DataPacket() throws Exception
13681391
13691392 waitForInitialization (dataReader .getId ());
13701393 testCI .notifyData ();
1371- while (dataReader .isRunning ())
1394+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
13721395 Thread .sleep (30 );
13731396
13741397 // Verify the result.
@@ -1410,7 +1433,7 @@ public final void testDataReaderReceivePacketRXIO16DataPacket() throws Exception
14101433
14111434 waitForInitialization (dataReader .getId ());
14121435 testCI .notifyData ();
1413- while (dataReader .isRunning ())
1436+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
14141437 Thread .sleep (30 );
14151438
14161439 // Verify the result.
@@ -1452,7 +1475,7 @@ public final void testDataReaderReceivePacketRXIOPacket() throws Exception {
14521475
14531476 waitForInitialization (dataReader .getId ());
14541477 testCI .notifyData ();
1455- while (dataReader .isRunning ())
1478+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
14561479 Thread .sleep (30 );
14571480
14581481 // Verify the result.
@@ -1494,7 +1517,7 @@ public final void testDataReaderReceivePacketModemStatusPacket() throws Exceptio
14941517
14951518 waitForInitialization (dataReader .getId ());
14961519 testCI .notifyData ();
1497- while (dataReader .isRunning ())
1520+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
14981521 Thread .sleep (30 );
14991522
15001523 // Verify the result.
@@ -1536,7 +1559,7 @@ public final void testDataReaderReceivePacketExplicitIndicatorDigiPacket() throw
15361559
15371560 waitForInitialization (dataReader .getId ());
15381561 testCI .notifyData ();
1539- while (dataReader .isRunning ())
1562+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
15401563 Thread .sleep (30 );
15411564
15421565 // Verify the result.
@@ -1578,7 +1601,7 @@ public final void testDataReaderReceivePacketExplicitIndicatorPacket() throws Ex
15781601
15791602 waitForInitialization (dataReader .getId ());
15801603 testCI .notifyData ();
1581- while (dataReader .isRunning ())
1604+ while (dataReader .isRunning () || ! testCI . transmissionFinished )
15821605 Thread .sleep (30 );
15831606
15841607 // Verify the result.
@@ -1600,10 +1623,10 @@ public final void testDataReaderReceivePacketIOExceptionWhenReading() throws Exc
16001623 Mockito .doAnswer (new Answer <XBeePacket >() {
16011624 @ Override
16021625 public XBeePacket answer (InvocationOnMock invocation ) throws Throwable {
1603- if (testCI .alreadyRead )
1626+ if (testCI .isAlreadyRead () )
16041627 return null ;
16051628
1606- testCI .alreadyRead = true ;
1629+ testCI .setAlreadyRead () ;
16071630 throw new IOException ("Exception when reading" );
16081631 }
16091632 }).when (mockInput ).read ();
@@ -1612,6 +1635,8 @@ public XBeePacket answer(InvocationOnMock invocation) throws Throwable {
16121635 IPacketReceiveListener packetListener = Mockito .mock (IPacketReceiveListener .class );
16131636 dataReader .addPacketReceiveListener (packetListener );
16141637
1638+ assertThat (testCI .isOpen (), is (equalTo (true )));
1639+
16151640 // Call the method under test.
16161641 dataReader .start ();
16171642
@@ -1623,6 +1648,7 @@ public XBeePacket answer(InvocationOnMock invocation) throws Throwable {
16231648 // Verify the result.
16241649 Mockito .verify (mockQueue , Mockito .times (0 )).addPacket (Mockito .any (XBeePacket .class ));
16251650 Mockito .verify (packetListener , Mockito .times (0 )).packetReceived (Mockito .any (XBeePacket .class ));
1651+ assertThat (testCI .isOpen (), is (equalTo (false )));
16261652 }
16271653
16281654 /**
@@ -1634,17 +1660,19 @@ public final void testDataReaderReceivePacketATmode() throws Exception {
16341660 TestConnectionInterface testCI = new TestConnectionInterface () {
16351661 @ Override
16361662 public InputStream getInputStream () {
1637- if (alreadyRead )
1663+ if (isAlreadyRead () )
16381664 return null ;
16391665
1640- alreadyRead = true ;
1666+ setAlreadyRead () ;
16411667 return mockInput ;
16421668 }
16431669 };
16441670 DataReader dataReader = new DataReader (testCI , OperatingMode .AT , mockDevice );
16451671 IPacketReceiveListener packetListener = Mockito .mock (IPacketReceiveListener .class );
16461672 dataReader .addPacketReceiveListener (packetListener );
16471673
1674+ assertThat (testCI .isOpen (), is (equalTo (true )));
1675+
16481676 // Call the method under test.
16491677 dataReader .start ();
16501678
@@ -1657,6 +1685,7 @@ public InputStream getInputStream() {
16571685 Mockito .verify (mockInput , Mockito .times (0 )).read ();
16581686 Mockito .verify (mockQueue , Mockito .times (0 )).addPacket (Mockito .any (XBeePacket .class ));
16591687 Mockito .verify (packetListener , Mockito .times (0 )).packetReceived (Mockito .any (XBeePacket .class ));
1688+ assertThat (testCI .isOpen (), is (equalTo (false )));
16601689 }
16611690
16621691 /**
@@ -1668,14 +1697,16 @@ public final void testDataReaderReceivePacketNullInputStream() throws Exception
16681697 TestConnectionInterface testCI = new TestConnectionInterface () {
16691698 @ Override
16701699 public InputStream getInputStream () {
1671- alreadyRead = true ;
1700+ setAlreadyRead () ;
16721701 return null ;
16731702 }
16741703 };
16751704 DataReader dataReader = new DataReader (testCI , OperatingMode .AT , mockDevice );
16761705 IPacketReceiveListener packetListener = Mockito .mock (IPacketReceiveListener .class );
16771706 dataReader .addPacketReceiveListener (packetListener );
16781707
1708+ assertThat (testCI .isOpen (), is (equalTo (true )));
1709+
16791710 // Call the method under test.
16801711 dataReader .start ();
16811712
@@ -1688,5 +1719,6 @@ public InputStream getInputStream() {
16881719 Mockito .verify (mockInput , Mockito .times (0 )).read ();
16891720 Mockito .verify (mockQueue , Mockito .times (0 )).addPacket (Mockito .any (XBeePacket .class ));
16901721 Mockito .verify (packetListener , Mockito .times (0 )).packetReceived (Mockito .any (XBeePacket .class ));
1722+ assertThat (testCI .isOpen (), is (equalTo (false )));
16911723 }
16921724}
0 commit comments