1   /* Contributed in the public domain.
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.utils;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.Collections;
22  import java.util.List;
23  import java.util.stream.Collectors;
24  
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.BeforeAll;
27  import org.junit.jupiter.api.BeforeEach;
28  import org.junit.jupiter.api.Test;
29  import org.orekit.Utils;
30  import org.orekit.errors.OrekitMessages;
31  import org.orekit.errors.TimeStampedCacheException;
32  import org.orekit.time.AbsoluteDate;
33  
34  /**
35   * Unit tests for {@link ImmutableTimeStampedCache}.
36   *
37   * @author Evan Ward
38   */
39  public class ImmutableTimeStampedCacheTest {
40  
41      /**
42       * arbitrary date
43       */
44      private static final AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
45  
46      /**
47       * set Orekit data for useful debugging messages from dates.
48       */
49      @BeforeAll
50      public static void setUpBefore() {
51          Utils.setDataRoot("regular-data");
52      }
53  
54      /**
55       * data provided to {@link #cache}
56       */
57      private List<AbsoluteDate> data;
58  
59      /**
60       * subject under test
61       */
62      private ImmutableTimeStampedCache<AbsoluteDate> cache;
63  
64      /**
65       * create {@link #cache} and {@link #data} with neighborsSize = 3
66       */
67      @BeforeEach
68      public void setUp() {
69          data = Arrays.asList(date, date.shiftedBy(1), date.shiftedBy(2),
70                               date.shiftedBy(3), date.shiftedBy(4),
71                               date.shiftedBy(5));
72          cache = new ImmutableTimeStampedCache<AbsoluteDate>(3, data);
73      }
74  
75      /**
76       * check
77       * {@link ImmutableTimeStampedCache#ImmutableTimeStampedCache(int, java.util.Collection)}
78       */
79      @Test
80      public void testImmutableTimeStampedCache() {
81          // exception for neighborsSize > data.size()
82          try {
83              new ImmutableTimeStampedCache<AbsoluteDate>(data.size() + 1, data);
84              Assertions.fail("Expected Exception");
85          } catch (IllegalArgumentException e) {
86              // expected
87          }
88  
89          // exception for non-positive neighborsSize
90          try {
91              new ImmutableTimeStampedCache<AbsoluteDate>(0, data);
92              Assertions.fail("Expected Exception");
93          } catch (IllegalArgumentException e) {
94              // expected
95          }
96  
97          // exception for null data
98          try {
99              new ImmutableTimeStampedCache<AbsoluteDate>(1, null);
100             Assertions.fail("Expected Exception");
101         } catch (NullPointerException e) {
102             // expected
103         }
104 
105         // exception for zero data
106         try {
107             new ImmutableTimeStampedCache<AbsoluteDate>(
108                                                         1,
109                                                         Collections
110                                                             .<AbsoluteDate> emptyList());
111             Assertions.fail("Expected Exception");
112         } catch (IllegalArgumentException e) {
113             // expected
114         }
115     }
116 
117     /**
118      * check {@link ImmutableTimeStampedCache#getNeighbors(AbsoluteDate)} at a
119      * series of different dates designed to test all logic paths.
120      *
121      * @throws TimeStampedCacheException
122      */
123     @Test
124     public void testGetNeighbors()
125         throws TimeStampedCacheException {
126         // setup
127         int size = data.size();
128 
129         // actions + verify
130 
131         // before fist data
132         try {
133             cache.getNeighbors(data.get(0).shiftedBy(-1));
134             Assertions.fail("Expected Exception");
135         } catch (TimeStampedCacheException e) {
136             // expected
137             Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_BEFORE, e.getSpecifier());
138         }
139 
140         // on fist date
141         Assertions.assertArrayEquals(cache.getNeighbors(data.get(0)).toArray(), data
142             .subList(0, 3).toArray());
143         // between fist and second date
144         Assertions.assertArrayEquals(cache.getNeighbors(data.get(0).shiftedBy(0.5))
145             .toArray(), data.subList(0, 3).toArray());
146         // in the middle on a date
147         Assertions.assertArrayEquals(cache.getNeighbors(data.get(2)).toArray(), data
148             .subList(1, 4).toArray());
149         // in the middle between dates
150         Assertions.assertArrayEquals(cache.getNeighbors(data.get(2).shiftedBy(0.5))
151             .toArray(), data.subList(1, 4).toArray());
152         // just before last date
153         Assertions.assertArrayEquals(cache
154             .getNeighbors(data.get(size - 1).shiftedBy(-0.5)).toArray(), data
155             .subList(size - 3, size).toArray());
156         // on last date
157         Assertions.assertArrayEquals(cache.getNeighbors(data.get(size - 1)).toArray(),
158                           data.subList(size - 3, size).toArray());
159 
160         // after last date
161         AbsoluteDate central = data.get(size - 1).shiftedBy(1);
162         try {
163             cache.getNeighbors(central);
164             Assertions.fail("Expected Exception");
165         } catch (TimeStampedCacheException e) {
166             // expected
167            Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_AFTER, e.getSpecifier());
168         }
169     }
170 
171     /** Check findIndex(...) returns results on a half closed interval. */
172     @Test
173     public void testGetNeighborsSingle() {
174         // setup
175         cache = new ImmutableTimeStampedCache<>(1, data);
176         int size = data.size();
177 
178         // actions + verify
179         // on fist date
180         Assertions.assertArrayEquals(
181                 cache.getNeighbors(data.get(0)).toArray(),
182                 data.subList(0, 1).toArray());
183         // between fist and second date
184         Assertions.assertArrayEquals(
185                 cache.getNeighbors(data.get(0).shiftedBy(0.5)).toArray(),
186                 data.subList(0, 1).toArray());
187         // in the middle on a date
188         Assertions.assertArrayEquals(
189                 cache.getNeighbors(data.get(2)).toArray(),
190                 data.subList(2, 3).toArray());
191         // in the middle between dates
192         Assertions.assertArrayEquals(
193                 cache.getNeighbors(data.get(2).shiftedBy(0.1)).toArray(),
194                 data.subList(2, 3).toArray());
195         // just before last date
196         Assertions.assertArrayEquals(
197                 cache.getNeighbors(data.get(size - 1).shiftedBy(-0.1)).toArray(),
198                 data.subList(size - 2, size - 1).toArray());
199         // on last date
200         Assertions.assertArrayEquals(
201                 cache.getNeighbors(data.get(size - 1)).toArray(),
202                 data.subList(size - 1, size).toArray());
203     }
204 
205     /**
206      * check {@link ImmutableTimeStampedCache#getMaxNeighborsSize()}
207      */
208     @Test
209     public void testGetNeighborsSize() {
210         Assertions.assertEquals(cache.getMaxNeighborsSize(), 3);
211     }
212 
213     /**
214      * check {@link ImmutableTimeStampedCache#getEarliest()}
215      */
216     @Test
217     public void testGetEarliest() {
218         Assertions.assertEquals(cache.getEarliest(), data.get(0));
219     }
220 
221     /**
222      * check {@link ImmutableTimeStampedCache#getLatest()}
223      */
224     @Test
225     public void testGetLatest() {
226         Assertions.assertEquals(cache.getLatest(), data.get(data.size() - 1));
227     }
228 
229     /**
230      * check {@link ImmutableTimeStampedCache#getAll()}
231      */
232     @Test
233     public void testGetAll() {
234         Assertions.assertArrayEquals(cache.getAll().toArray(), data.toArray());
235     }
236 
237     /**
238      * check that the cache is immutable by changing the data passed in the
239      * constructor and returned from methods.
240      *
241      * @throws TimeStampedCacheException
242      */
243     @Test
244     public void testImmutable()
245         throws TimeStampedCacheException {
246         // setup
247         List<AbsoluteDate> actuals;
248         List<AbsoluteDate> expecteds = new ArrayList<AbsoluteDate>(data);
249         AbsoluteDate different = date.shiftedBy(-50);
250 
251         // actions + verify
252 
253         // check constructor
254         data.set(0, different);
255         Assertions.assertArrayEquals(cache.getAll().toArray(), expecteds.toArray());
256 
257         // check getAll
258         actuals = cache.getAll();
259         try {
260             actuals.set(0, different);
261         } catch (UnsupportedOperationException e) {
262             // exception ok
263         }
264         Assertions.assertArrayEquals(cache.getAll().toArray(), expecteds.toArray());
265 
266         // check getNeighbors
267         actuals = cache.getNeighbors(date).collect(Collectors.toList());
268         Assertions.assertArrayEquals(cache.getAll().toArray(), expecteds.toArray());
269     }
270 
271     /**
272      * check {@link ImmutableTimeStampedCache#emptyCache()}.
273      */
274     @Test
275     public void testEmptyCache() {
276         // setup
277         cache = ImmutableTimeStampedCache.emptyCache();
278 
279         // actions + verify
280         try {
281             cache.getNeighbors(date);
282             Assertions.fail("Expected Exception");
283         } catch (TimeStampedCacheException e) {
284             // expected
285         }
286         try {
287             cache.getEarliest();
288             Assertions.fail("Expected Exception");
289         } catch (IllegalStateException e) {
290             // expected
291         }
292         try {
293             cache.getLatest();
294             Assertions.fail("Expected Exception");
295         } catch (IllegalStateException e) {
296             // expected
297         }
298         Assertions.assertEquals(cache.getAll().size(), 0);
299         Assertions.assertEquals(cache.getMaxNeighborsSize(), 0);
300     }
301 
302     @Test
303     public void testNonLinear() {
304         final ImmutableTimeStampedCache<AbsoluteDate> nonLinearCache = new ImmutableTimeStampedCache<>(2,
305                         Arrays.asList(date.shiftedBy(10),
306                                       date.shiftedBy(14),
307                                       date.shiftedBy(18),
308                                       date.shiftedBy(23),
309                                       date.shiftedBy(30),
310                                       date.shiftedBy(36),
311                                       date.shiftedBy(45),
312                                       date.shiftedBy(55),
313                                       date.shiftedBy(67),
314                                       date.shiftedBy(90),
315                                       date.shiftedBy(118)));
316         for (double dt = 10; dt < 118; dt += 0.01) {
317             checkNeighbors(nonLinearCache, dt);
318         }
319     }
320 
321     private void checkNeighbors(final ImmutableTimeStampedCache<AbsoluteDate> nonLinearCache,
322                                 final double offset) {
323         List<AbsoluteDate> s = nonLinearCache.getNeighbors(date.shiftedBy(offset)).collect(Collectors.toList());
324         Assertions.assertEquals(2, s.size());
325         Assertions.assertTrue(s.get(0).durationFrom(date) <= offset);
326         Assertions.assertTrue(s.get(1).durationFrom(date) >  offset);
327     }
328 
329 }