2424
2525import java .util .List ;
2626import java .util .Random ;
27+ import java .util .concurrent .ExecutorService ;
28+ import java .util .concurrent .Executors ;
29+ import java .util .concurrent .TimeUnit ;
30+ import java .util .concurrent .atomic .AtomicInteger ;
2731
2832import static org .junit .Assert .assertEquals ;
2933import static org .junit .Assert .assertTrue ;
@@ -37,6 +41,7 @@ public class EncodeDecodeTest {
3741 private static final int NUMBER_OF_POINTS = 5000 ;
3842 private static final int LOG_LINE_EVERY = 500 ;
3943
44+
4045 @ Test
4146 public void encodeDecodeTestFixedSeed () throws Exception {
4247 final long seed = 1431977987367L ;
@@ -51,13 +56,19 @@ public void encodeDecodeTestRandomSeed() throws Exception {
5156 doEncodeDecode (seed );
5257 }
5358
54- private static void doEncodeDecode (final long seed ) throws UnknownMapcodeException {
59+ private static void doEncodeDecode (final long seed ) throws InterruptedException {
60+
61+ // Keep error count and create thread pool.
62+ final AtomicInteger errors = new AtomicInteger (0 );
63+ final int threads = Runtime .getRuntime ().availableProcessors ();
64+ LOG .info ("encodeDecodeTest: Starting {} threads..." , threads );
65+ final ExecutorService executor = Executors .newFixedThreadPool (threads );
66+
5567 final Random randomGenerator = new Random (seed );
56- double maxDistancePrecision0Meters = 0.0 ;
57- double maxDistancePrecision1Meters = 0.0 ;
58- double maxDistancePrecision2Meters = 0.0 ;
5968 for (int i = 0 ; i < NUMBER_OF_POINTS ; i ++) {
60- boolean showLogLine = ((i % LOG_LINE_EVERY ) == 0 );
69+ if ((i % LOG_LINE_EVERY ) == 0 ) {
70+ LOG .info ("encodeDecodeTest: #{}/{}" , i , NUMBER_OF_POINTS );
71+ }
6172
6273 // Encode location.
6374 final Point encode = Point .fromUniformlyDistributedRandomPoints (randomGenerator );
@@ -73,63 +84,61 @@ private static void doEncodeDecode(final long seed) throws UnknownMapcodeExcepti
7384 assertEquals ("encodeToInternational failed, result=" + resultsAll ,
7485 resultsAll .get (resultsAll .size () - 1 ), mapcodeInternational );
7586
76- // Every point must have a Mapcode.
77- boolean found = false ;
78-
7987 // Walk through the list in reverse order to get International first.
8088 for (final Territory territory : Territory .values ()) {
81- final List <Mapcode > resultsLimited = MapcodeCodec .encode (latDeg , lonDeg , territory );
82- for (final Mapcode mapcode : resultsLimited ) {
83- found = true ;
84-
85- // Check if the territory matches.
86- assertEquals (territory , mapcode .getTerritory ());
87-
88- // Check max distance.
89- final String codePrecision0 = mapcode .getCode (0 );
90- final String codePrecision1 = mapcode .getCode (1 );
91- final String codePrecision2 = mapcode .getCode (2 );
92-
93- final Point decodeLocationPrecision0 = MapcodeCodec .decode (codePrecision0 , territory );
94- final Point decodeLocationPrecision1 = MapcodeCodec .decode (codePrecision1 , territory );
95- final Point decodeLocationPrecision2 = MapcodeCodec .decode (codePrecision2 , territory );
96-
97- final double distancePrecision0Meters = Point .distanceInMeters (encode , decodeLocationPrecision0 );
98- final double distancePrecision1Meters = Point .distanceInMeters (encode , decodeLocationPrecision1 );
99- final double distancePrecision2Meters = Point .distanceInMeters (encode , decodeLocationPrecision2 );
100-
101- maxDistancePrecision0Meters = Math .max (maxDistancePrecision0Meters , distancePrecision0Meters );
102- maxDistancePrecision1Meters = Math .max (maxDistancePrecision1Meters , distancePrecision1Meters );
103- maxDistancePrecision2Meters = Math .max (maxDistancePrecision2Meters , distancePrecision2Meters );
104-
105- assertTrue (mapcode + " distancePrecision0Meters=" + distancePrecision0Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (0 ),
106- distancePrecision0Meters < Mapcode .getSafeMaxOffsetInMeters (0 ));
107- assertTrue (mapcode + "distancePrecision1Meters=" + distancePrecision1Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (1 ),
108- distancePrecision1Meters < Mapcode .getSafeMaxOffsetInMeters (1 ));
109- assertTrue (mapcode + "distancePrecision2Meters=" + distancePrecision2Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (2 ),
110- distancePrecision2Meters < Mapcode .getSafeMaxOffsetInMeters (2 ));
111-
112- // Check conversion from/to alphabets.
113- for (final Alphabet alphabet : Alphabet .values ()) {
114- final String mapcodeAlphabet = mapcode .getCode (alphabet );
115- final String mapcodeAscii = Mapcode .convertStringToPlainAscii (mapcodeAlphabet );
116- assertEquals (mapcode + " alphabet=" + alphabet + ", original=" + codePrecision0 +
117- ", mapcodeAlphabet=" + mapcodeAlphabet + ", mapcodeAscii=" + mapcodeAscii ,
118- codePrecision0 , mapcodeAscii );
119- }
120-
121- if (showLogLine ) {
122- LOG .info ("encodeDecodeTest: #{}/{}, result={}, mapcode={}, territory={} --> " +
123- "lat={}, lon={}; delta={}" , i , NUMBER_OF_POINTS ,
124- mapcode , codePrecision0 , territory .getFullName (), decodeLocationPrecision0 .getLatDeg (),
125- decodeLocationPrecision0 .getLonDeg (), distancePrecision0Meters );
89+ executor .execute (() -> {
90+ try {
91+ final List <Mapcode > resultsLimited = MapcodeCodec .encode (latDeg , lonDeg , territory );
92+ for (final Mapcode mapcode : resultsLimited ) {
93+
94+ // Check if the territory matches.
95+ assertEquals (territory , mapcode .getTerritory ());
96+
97+ // Check max distance.
98+ final String codePrecision0 = mapcode .getCode (0 );
99+ final String codePrecision1 = mapcode .getCode (1 );
100+ final String codePrecision2 = mapcode .getCode (2 );
101+
102+ final Point decodeLocationPrecision0 = MapcodeCodec .decode (codePrecision0 , territory );
103+ final Point decodeLocationPrecision1 = MapcodeCodec .decode (codePrecision1 , territory );
104+ final Point decodeLocationPrecision2 = MapcodeCodec .decode (codePrecision2 , territory );
105+
106+ final double distancePrecision0Meters = Point .distanceInMeters (encode , decodeLocationPrecision0 );
107+ final double distancePrecision1Meters = Point .distanceInMeters (encode , decodeLocationPrecision1 );
108+ final double distancePrecision2Meters = Point .distanceInMeters (encode , decodeLocationPrecision2 );
109+
110+ if (distancePrecision0Meters >= Mapcode .getSafeMaxOffsetInMeters (0 )) {
111+ LOG .error ("encodeDecodeTest: " + mapcode + " distancePrecision0Meters = " + distancePrecision0Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (0 ));
112+ errors .getAndIncrement ();
113+ }
114+ if (distancePrecision1Meters >= Mapcode .getSafeMaxOffsetInMeters (1 )) {
115+ LOG .error ("encodeDecodeTest: " + mapcode + " distancePrecision1Meters = " + distancePrecision1Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (1 ));
116+ errors .getAndIncrement ();
117+ }
118+ if (distancePrecision2Meters >= Mapcode .getSafeMaxOffsetInMeters (2 )) {
119+ LOG .error ("encodeDecodeTest: " + mapcode + " distancePrecision2Meters = " + distancePrecision2Meters + " >= " + Mapcode .getSafeMaxOffsetInMeters (2 ));
120+ errors .getAndIncrement ();
121+ }
122+
123+ // Check conversion from/to alphabets.
124+ for (final Alphabet alphabet : Alphabet .values ()) {
125+ final String mapcodeAlphabet = mapcode .getCode (alphabet );
126+ final String mapcodeAscii = Mapcode .convertStringToPlainAscii (mapcodeAlphabet );
127+ if (!codePrecision0 .equals (mapcodeAscii )) {
128+ LOG .error ("encodeDecodeTest: " + mapcode + " alphabet=" + alphabet + ", original=" + codePrecision0 +
129+ ", mapcodeAlphabet=" + mapcodeAlphabet + ", mapcodeAscii=" + mapcodeAscii );
130+ }
131+ }
132+ }
133+ } catch (final Exception e ) {
134+ LOG .error ("encodeDecodeTest: Unexpected exception: " , e );
135+ errors .getAndIncrement ();
126136 }
127- showLogLine = false ;
128- }
137+ });
129138 }
130- assertTrue (found );
131139 }
132- LOG .debug ("encodeDecodeTest: maximum distances, precision 0, 1, 2: {}, {}, {} meters, " ,
133- maxDistancePrecision0Meters , maxDistancePrecision1Meters , maxDistancePrecision2Meters );
140+ executor .shutdown ();
141+ executor .awaitTermination (60 , TimeUnit .SECONDS );
142+ assertEquals ("Found errors" , 0 , errors .get ());
134143 }
135144}
0 commit comments