/* * ****************************************************************************** * Cloud Foundry * Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. * ******************************************************************************* */ package org.cloudfoundry.identity.uaa.cache; import org.cloudfoundry.identity.uaa.util.TimeService; import org.junit.Before; import org.junit.Test; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class ExpiringUrlCacheTests { public static final int EXPIRING_TIME_MILLIS = 10 * 60 * 1000; private ExpiringUrlCache cache; private TimeService ticker; private RestTemplate template; private String uri; private byte[] content = new byte[1024]; @Before public void setup() { Arrays.fill(content, (byte) 1); ticker = mock(TimeService.class); when(ticker.getCurrentTimeMillis()).thenAnswer(e -> System.currentTimeMillis()); cache = new ExpiringUrlCache(EXPIRING_TIME_MILLIS, ticker, 2); template = mock(RestTemplate.class); when(template.getForObject(any(URI.class), any())).thenReturn(content, new byte[1024]); uri = "http://localhost:8080/uaa/.well-known/openid-configuration"; } @Test public void correct_method_invoked_on_rest_template() throws URISyntaxException { cache.getUrlContent(uri, template); verify(template, times(1)).getForObject(eq(new URI(uri)), same((new byte[0]).getClass())); } @Test(expected = IllegalArgumentException.class) public void incorrect_uri_throws_illegal_argument_exception() { uri = "invalid value"; cache.getUrlContent(uri, template); } @Test public void rest_client_exception_returns_null() { template = mock(RestTemplate.class); when(template.getForObject(any(URI.class), any())).thenThrow(new RestClientException("mock")); assertNull(cache.getUrlContent(uri, template)); assertEquals(0, cache.size()); } @Test public void calling_twice_uses_cache() throws Exception { byte[] c1 = cache.getUrlContent(uri, template); byte[] c2 = cache.getUrlContent(uri, template); verify(template, times(1)).getForObject(eq(new URI(uri)), same((new byte[0]).getClass())); assertSame(c1, c2); assertEquals(1, cache.size()); } @Test public void entry_expires_on_time() throws Exception { when(ticker.getCurrentTimeMillis()).thenReturn(System.currentTimeMillis(), System.currentTimeMillis() + EXPIRING_TIME_MILLIS + 10000); byte[] c1 = cache.getUrlContent(uri, template); byte[] c2 = cache.getUrlContent(uri, template); verify(template, times(2)).getForObject(eq(new URI(uri)), same((new byte[0]).getClass())); assertNotSame(c1, c2); } @Test public void test_google_returns_same_array() { uri = "https://accounts.google.com/.well-known/openid-configuration"; byte[] c1 = cache.getUrlContent(uri, new RestTemplate()); byte[] c2 = cache.getUrlContent(uri, new RestTemplate()); assertNotNull(c1); assertSame(c1, c2); } @Test public void cache_should_start_empty() { assertEquals(0, cache.size()); } @Test public void max_entries_is_respected() throws URISyntaxException { String uri1 = "http://test1.com"; String uri2 = "http://test2.com"; String uri3 = "http://test3.com"; byte[] c1 = new byte[1024]; byte[] c2 = new byte[1024]; byte[] c3 = new byte[1024]; template = mock(RestTemplate.class); when(template.getForObject(eq(new URI(uri1)), any())).thenReturn(c1); when(template.getForObject(eq(new URI(uri2)), any())).thenReturn(c2); when(template.getForObject(eq(new URI(uri3)), any())).thenReturn(c3); for (String uri : Arrays.asList(uri1, uri1, uri2, uri2, uri3, uri3)) { cache.getUrlContent(uri, template); } for (String uri : Arrays.asList(uri1, uri2, uri3)) { verify(template, times(1)).getForObject(eq(new URI(uri)), same((new byte[0]).getClass())); } assertEquals(2, cache.size()); } }