1 /*******************************************************************************
3 * * ===========================================================================
4 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5 * * ===========================================================================
6 * * Licensed under the Apache License, Version 2.0 (the "License");
7 * * you may not use this file except in compliance with the License.
8 * * You may obtain a copy of the License at
10 * * http://www.apache.org/licenses/LICENSE-2.0
12 * * Unless required by applicable law or agreed to in writing, software
13 * * distributed under the License is distributed on an "AS IS" BASIS,
14 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * * See the License for the specific language governing permissions and
16 * * limitations under the License.
17 * * ============LICENSE_END====================================================
20 ******************************************************************************/
22 package org.onap.aaf.cadi.test;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertThat;
26 import static org.junit.Assert.assertTrue;
27 import static org.hamcrest.CoreMatchers.is;
28 import static org.hamcrest.CoreMatchers.nullValue;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.when;
32 import java.io.ByteArrayOutputStream;
33 import java.io.IOException;
34 import java.io.PrintStream;
35 import java.lang.reflect.Field;
36 import java.security.Principal;
37 import java.util.ArrayList;
38 import java.util.List;
40 import org.junit.After;
41 import org.junit.Before;
42 import org.junit.BeforeClass;
43 import org.junit.Test;
44 import org.mockito.Mock;
45 import org.mockito.MockitoAnnotations;
46 import org.onap.aaf.cadi.AbsUserCache;
47 import org.onap.aaf.cadi.Access;
48 import org.onap.aaf.cadi.CachedPrincipal.Resp;
49 import org.onap.aaf.cadi.CachingLur;
50 import org.onap.aaf.cadi.GetCred;
51 import org.onap.aaf.cadi.Permission;
52 import org.onap.aaf.cadi.PropAccess;
53 import org.onap.aaf.cadi.User;
54 import org.onap.aaf.cadi.lur.LocalPermission;
55 import org.onap.aaf.cadi.principal.CachedBasicPrincipal;
57 public class JU_AbsUserCache {
59 @Mock private CachingLur<Permission> cl;
60 @Mock private Principal principal;
61 @Mock private CachedBasicPrincipal cbp;
62 @Mock private LocalPermission permission1;
63 @Mock private LocalPermission permission2;
65 private Access access;
67 private ByteArrayOutputStream outStream;
69 private String name1 = "name1";
70 private String name2 = "name2";
71 private byte[] password = "password".getBytes();
73 private static Field timerField;
76 public static void setupOnce() throws Exception {
77 timerField = AbsUserCache.class.getDeclaredField("timer");
78 timerField.setAccessible(true);
82 public void setup() throws Exception {
83 MockitoAnnotations.initMocks(this);
85 outStream = new ByteArrayOutputStream();
86 System.setOut(new PrintStream(outStream));
88 // This must happen after changing System.out
89 access = new PropAccess();
91 when(permission1.getKey()).thenReturn("NewKey1");
92 when(permission2.getKey()).thenReturn("NewKey2");
94 timerField.set(null, null);
98 public void tearDown() throws Exception {
99 System.setOut(System.out);
100 timerField.set(null, null);
103 @SuppressWarnings("unused")
105 public void constructorTest() {
106 int cleanInterval = 65000;
107 int maxInterval = 70000;
109 AbsUserCacheStub<Permission> aucs1 = new AbsUserCacheStub<Permission>(access, cleanInterval, maxInterval, Integer.MAX_VALUE);
110 String output = outStream.toString().split(" ", 2)[1];
111 StringBuilder expected = new StringBuilder();
112 expected.append("INIT [cadi] Cleaning Thread initialized with interval of ");
113 expected.append(String.valueOf(cleanInterval));
114 expected.append(" ms and max objects of ");
115 expected.append(String.valueOf(maxInterval));
116 expected.append(System.lineSeparator());
117 assertThat(output, is(expected.toString()));
120 AbsUserCacheStub<Permission> aucs2 = new AbsUserCacheStub<Permission>(access, cleanInterval, maxInterval, Integer.MAX_VALUE);
121 output = outStream.toString().split(" ", 2)[1];
122 expected = new StringBuilder();
123 expected.append("INIT [cadi] Cleaning Thread initialized with interval of ");
124 expected.append(String.valueOf(cleanInterval));
125 expected.append(" ms and max objects of ");
126 expected.append(String.valueOf(maxInterval));
127 expected.append(System.lineSeparator());
128 assertThat(output, is(expected.toString()));
130 AbsUserCacheStub<Permission> aucs3 = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
131 AbsUserCacheStub<Permission> aucs4 = new AbsUserCacheStub<Permission>(aucs1);
134 AbsUserCacheCLStub<Permission> auccls1 = new AbsUserCacheCLStub<Permission>(aucs1);
136 auccls1 = new AbsUserCacheCLStub<Permission>(aucs1);
137 AbsUserCacheCLStub<Permission> auccls2 = new AbsUserCacheCLStub<Permission>(aucs3);
141 public void setLurTest() {
142 AbsUserCacheStub<Permission> aucs1 = new AbsUserCacheStub<Permission>(access, 65000, 70000, Integer.MAX_VALUE);
143 AbsUserCacheStub<Permission> aucs2 = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
149 public void addUserGetUserTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
150 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
151 User<Permission> user;
153 // Test adding a user with a principal (non-GetCred). user does not have a cred
154 // Then test getting that user
155 when(principal.getName()).thenReturn(name1);
156 user = new User<Permission>(principal, 0);
158 assertThat(aucs.getUser(principal), is(user));
160 // Test adding a user with a principal (GetCred). user does not have a cred
161 // Then test getting that user
162 GetCredStub gc = new GetCredStub();
163 user = new User<Permission>(gc, 0);
165 assertThat(aucs.getUser(gc), is(user));
167 // Test adding a user with no principal
168 // Then test getting that user via his name and cred
169 user = new User<Permission>(name2, password);
171 assertThat(aucs.getUser(name2, password), is(user));
173 // Test getting a user by a CachedBasicPrincipal
174 when(cbp.getName()).thenReturn(name2);
175 when(cbp.getCred()).thenReturn(password);
176 assertThat(aucs.getUser(cbp), is(user));
178 // Force the user to expire, then test that he is no longer in the cache
179 Field permExpiresField = User.class.getDeclaredField("permExpires");
180 permExpiresField.setAccessible(true);
181 permExpiresField.set(user, 0);
182 assertThat(aucs.getUser(name2, password), is(nullValue()));
184 // Test adding a user with a custom key
185 // Then test gettin that user
186 user = new User<Permission>(principal, 0);
187 String key = principal.getName() + "NoCred";
188 aucs.addUser(key, user);
189 assertThat(aucs.getUser(principal), is(user));
191 // Test that getUser returns null for principals that don't match any users
192 when(principal.getName()).thenReturn("not in the cache");
193 assertThat(aucs.getUser(principal), is(nullValue()));
195 // That that getUser returns null for name/creds that are not in the cache
196 assertThat(aucs.getUser("not a real user", "not in the cache".getBytes()), is(nullValue()));
200 public void removeTest() {
201 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
202 User<Permission> user;
204 when(principal.getName()).thenReturn(name1);
205 user = new User<Permission>(principal);
206 // Add a user with a principal
208 // Check that the user is in the cache
209 assertThat(aucs.getUser(principal), is(user));
211 when(principal.getName()).thenReturn(name1 + "NoCred");
213 // Check that the user is no longer in the cache
214 when(principal.getName()).thenReturn(name1);
215 assertThat(aucs.getUser(principal), is(nullValue()));
217 // Add the user again
219 // Check that the user is in the cache
220 assertThat(aucs.getUser(principal), is(user));
221 // Remove the user by name
222 aucs.remove(name1 + "NoCred");
223 // Check that the user is no longer in the cache
224 assertThat(aucs.getUser(principal), is(nullValue()));
226 // Coverage test - attempt to remove a user that is not in the cache
227 aucs.remove(name1 + "NoCred");
228 assertThat(aucs.getUser(principal), is(nullValue()));
232 public void clearAllTest() {
233 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
234 User<Permission> user1;
235 User<Permission> user2;
237 // Add some users to the cache
238 when(principal.getName()).thenReturn(name1);
239 user1 = new User<Permission>(principal);
240 when(principal.getName()).thenReturn(name2);
241 user2 = new User<Permission>(principal);
245 // Check that the users are in the cache
246 when(principal.getName()).thenReturn(name1);
247 assertThat(aucs.getUser(principal), is(user1));
248 when(principal.getName()).thenReturn(name2);
249 assertThat(aucs.getUser(principal), is(user2));
254 // Check that the users are no longer in the cache
255 when(principal.getName()).thenReturn(name1);
256 assertThat(aucs.getUser(principal), is(nullValue()));
257 when(principal.getName()).thenReturn(name2);
258 assertThat(aucs.getUser(principal), is(nullValue()));
262 public void dumpInfoTest() {
263 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
264 User<Permission> user1;
265 User<Permission> user2;
267 Principal principal1 = mock(Principal.class);
268 Principal principal2 = mock(Principal.class);
269 when(principal1.getName()).thenReturn(name1);
270 when(principal2.getName()).thenReturn(name2);
272 // Add some users with permissions to the cache
273 user1 = new User<Permission>(principal1);
274 user1.add(permission1);
275 user1.add(permission2);
276 user2 = new User<Permission>(principal2);
277 user2.add(permission1);
278 user2.add(permission2);
283 List<AbsUserCache<Permission>.DumpInfo> dumpInfo = aucs.dumpInfo();
284 assertThat(dumpInfo.size(), is(2));
287 List<String> names = new ArrayList<>();
290 List<String> permissions = new ArrayList<>();
291 permissions.add("NewKey1");
292 permissions.add("NewKey2");
294 // We need to use "contains" because the dumpInfo was created from a list, so we don't know it's order
295 for (AbsUserCache<Permission>.DumpInfo di : dumpInfo) {
296 assertTrue(names.contains(di.user));
297 for (String perm : di.perms) {
298 assertTrue(permissions.contains(perm));
304 public void handlesExclusivelyTest() {
305 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
306 assertFalse(aucs.handlesExclusively(permission1));
307 assertFalse(aucs.handlesExclusively(permission2));
311 public void destroyTest() {
312 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
314 aucs = new AbsUserCacheStub<Permission>(access, 1, 1, Integer.MAX_VALUE);
319 public void missTest() throws IOException {
320 AbsUserCacheStub<Permission> aucs = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE);
321 // Add the Miss to the missmap
322 assertTrue(aucs.addMiss("key", password)); // This one actually adds it
323 assertTrue(aucs.addMiss("key", password)); // this one doesn't really do anything
324 assertTrue(aucs.addMiss("key", password)); // neither does this one
325 assertFalse(aucs.addMiss("key", password)); // By this time, the missMap is tired of this nonsense, and retaliates
326 assertFalse(aucs.addMiss("key", password)); // Oh yea. He's angry
328 // Can't really test this due to visibility
329 aucs.missed("key", password);
332 AbsUserCacheStub<Permission> aucs1 = new AbsUserCacheStub<Permission>(access, 1, 1, Integer.MAX_VALUE);
333 aucs1.addMiss("key", password);
336 class AbsUserCacheStub<PERM extends Permission> extends AbsUserCache<PERM> {
337 public AbsUserCacheStub(Access access, long cleanInterval, int highCount, int usageCount) { super(access, cleanInterval, highCount, usageCount); }
338 public AbsUserCacheStub(AbsUserCache<PERM> cache) { super(cache); }
339 @Override public void setLur(CachingLur<PERM> lur) { super.setLur(lur); }
340 @Override public void addUser(User<PERM> user) { super.addUser(user); }
341 @Override public void addUser(String key, User<PERM> user) { super.addUser(key, user); }
342 @Override public User<PERM> getUser(Principal p) { return super.getUser(p); }
343 @Override public User<PERM> getUser(CachedBasicPrincipal p) { return super.getUser(p); }
344 @Override public User<PERM> getUser(String user, byte[] cred) { return super.getUser(user, cred); }
345 @Override public void remove(User<PERM> user) { super.remove(user); }
346 @Override public boolean addMiss(String key, byte[] bs) { return super.addMiss(key, bs); }
347 @Override public Miss missed(String key, byte[] bs) throws IOException { return super.missed(key, bs); }
350 class AbsUserCacheCLStub<PERM extends Permission> extends AbsUserCache<PERM> implements CachingLur<PERM> {
351 public AbsUserCacheCLStub(AbsUserCache<PERM> cache) { super(cache); }
352 @Override public Permission createPerm(String p) { return null; }
353 @Override public boolean fish(Principal bait, Permission ... pond) { return false; }
354 @Override public void fishAll(Principal bait, List<Permission> permissions) { }
355 @Override public boolean handles(Principal principal) { return false; }
356 @Override public Resp reload(User<PERM> user) { return null; }
357 @Override public void setDebug(String commaDelimIDsOrNull) { }
360 class GetCredStub implements Principal, GetCred {
361 @Override public byte[] getCred() { return password; }
362 @Override public String getName() { return name1; }