1616
1717import static org .junit .Assert .assertEquals ;
1818import static org .junit .Assert .assertTrue ;
19+ import static org .junit .Assert .fail ;
1920
2021import com .cloudant .client .api .ClientBuilder ;
2122import com .cloudant .client .api .CloudantClient ;
3233import org .junit .ClassRule ;
3334import org .junit .Test ;
3435
36+ import mockit .Expectations ;
37+ import mockit .Mocked ;
38+ import mockit .StrictExpectations ;
39+ import mockit .Verifications ;
40+
3541import java .io .ByteArrayInputStream ;
3642import java .net .URL ;
43+ import java .security .Security ;
44+ import java .security .SecurityPermission ;
3745import java .util .ArrayList ;
3846import java .util .List ;
3947import java .util .logging .Handler ;
@@ -51,7 +59,7 @@ public class LoggingTest {
5159 public static MockWebServer mockWebServer = new MockWebServer ();
5260
5361 private static CloudantClient client ;
54- private Logger logger ;
62+ private volatile Logger logger ;
5563 private VerificationLogHandler handler ;
5664
5765 @ BeforeClass
@@ -180,6 +188,158 @@ public void clientBuilderLogging() throws Exception {
180188 assertLogMessage ("Using default GSON builder" , 4 );
181189 }
182190
191+ /**
192+ * A basic DNS log test that can be called with different values.
193+ *
194+ * @param cacheValue the value to set for the cache lifetime
195+ *
196+ * @throws Exception if the test fails or errors
197+ */
198+ private void basicDnsLogTest (String cacheValue ) throws Exception {
199+ logger = setupLogger (ClientBuilder .class , Level .WARNING );
200+ String previous = Security .getProperty ("networkaddress.cache.ttl" );
201+ try {
202+ Security .setProperty ("networkaddress.cache.ttl" , cacheValue );
203+ CloudantClientHelper .getClientBuilder ().build ();
204+ } finally {
205+ // No way to unset a property, just reset to previous value
206+ // or set to 30 if it was null
207+ Security .setProperty ("networkaddress.cache.ttl" , (previous == null ) ? "30" : previous );
208+ }
209+ }
210+
211+ /**
212+ * Test that no warning is logged if the DNS lifetime is less than 30 s
213+ *
214+ * @throws Exception
215+ */
216+ @ Test
217+ public void dnsNoWarningLessThan30 () throws Exception {
218+ basicDnsLogTest ("29" );
219+ // Assert no warning was received
220+ assertEquals ("There should be no log entry" , 0 , handler .logEntries .size ());
221+ }
222+
223+ /**
224+ * Test that no warning is logged if DNS caching is disabled
225+ *
226+ * @throws Exception
227+ */
228+ @ Test
229+ public void dnsNoWarning0 () throws Exception {
230+ basicDnsLogTest ("0" );
231+ // Assert no warning was received
232+ assertEquals ("There should be no log entry" , 0 , handler .logEntries .size ());
233+ }
234+
235+ /**
236+ * Test that a warning is logged if DNS caching is set to cache forever
237+ *
238+ * @throws Exception
239+ */
240+ @ Test
241+ public void dnsWarningForever () throws Exception {
242+ basicDnsLogTest ("-1" );
243+ // Assert a warning was received
244+ assertEquals ("There should be 1 log entry" , 1 , handler .logEntries .size ());
245+ // Assert that it matches the expected pattern
246+ assertLogMessage ("DNS cache lifetime may be too long\\ . .*" , 0 );
247+ }
248+
249+ /**
250+ * Test that no warning is logged if the DNS lifetime is 30 s
251+ *
252+ * @throws Exception
253+ */
254+ @ Test
255+ public void dnsNoWarning30 () throws Exception {
256+ basicDnsLogTest ("30" );
257+ // Assert no warning was received
258+ assertEquals ("There should be no log entry" , 0 , handler .logEntries .size ());
259+ }
260+
261+
262+ /**
263+ * Test that a warning is logged if the DNS lifetime is longer than 30 s
264+ *
265+ * @throws Exception
266+ */
267+ @ Test
268+ public void dnsWarning31 () throws Exception {
269+ basicDnsLogTest ("31" );
270+ // Assert a warning was received
271+ assertEquals ("There should be 1 log entry" , 1 , handler .logEntries .size ());
272+ // Assert that it matches the expected pattern
273+ assertLogMessage ("DNS cache lifetime may be too long\\ . .*" , 0 );
274+ }
275+
276+ /**
277+ * Test that a warning is logged if the DNS lifetime cannot be checked because of security
278+ * permissions.
279+ *
280+ * @throws Exception
281+ */
282+ @ Test
283+ public void dnsWarningPermissionDenied (@ Mocked final SecurityManager mockSecurityManager )
284+ throws Exception {
285+
286+ // Record the mock expectations
287+ new Expectations () {
288+ {
289+ mockSecurityManager .checkPermission (new SecurityPermission ("getProperty" +
290+ ".networkaddress.cache.ttl" ));
291+ result = new SecurityException ("Test exception to deny property access." );
292+ times = 1 ;
293+ }
294+ };
295+ logger = setupLogger (ClientBuilder .class , Level .WARNING );
296+ try {
297+ System .setSecurityManager (mockSecurityManager );
298+ CloudantClientHelper .getClientBuilder ().build ();
299+ } finally {
300+ // Unset the mock security manager
301+ System .setSecurityManager (null );
302+ }
303+ // Assert a warning was received
304+ assertEquals ("There should be 1 log entry" , 1 , handler .logEntries .size ());
305+ // Assert that it matches the expected pattern
306+ assertLogMessage ("Permission denied to check Java DNS cache TTL\\ . .*" , 0 );
307+ }
308+
309+ /**
310+ * Test that a warning is logged if a security manager is in use and the DNS cache lifetime
311+ * property is unset.
312+ *
313+ * @throws Exception
314+ */
315+ @ Test
316+ public void dnsWarningDefaultWithSecurityManager (@ Mocked final SecurityManager
317+ mockSecurityManager ) throws Exception {
318+ // Record the mock expectations
319+ new Expectations () {
320+ {
321+ mockSecurityManager .checkPermission (new SecurityPermission ("getProperty" +
322+ ".networkaddress.cache.ttl" ));
323+ minTimes = 2 ; // Once to set, once to get, and once to reset
324+ maxTimes = 3 ; // Possible third call to reset the value, depending on test ordering
325+ }
326+ };
327+ try {
328+ System .setSecurityManager (mockSecurityManager );
329+ // We can't set null as a value and there are no APIs for clearing a value. Another test
330+ // may already have changed the value so we just set it to something invalid "a" to get
331+ // a default value.
332+ basicDnsLogTest ("a" );
333+ } finally {
334+ // Unset the mock security manager
335+ System .setSecurityManager (null );
336+ }
337+ // Assert a warning was received
338+ assertEquals ("There should be 1 log entry" , 1 , handler .logEntries .size ());
339+ // Assert that it matches the expected pattern
340+ assertLogMessage ("DNS cache lifetime may be too long\\ . .*" , 0 );
341+ }
342+
183343 /**
184344 * Set a LogManager configuration property and assert it was set correctly
185345 *
0 commit comments