1 /*
2  * Copyright 2002-2008 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.aop.target.dynamic;
18 
19 import static org.junit.Assert.*;
20 
21 import org.junit.Test;
22 
23 /**
24  * @author Rob Harrop
25  * @author Chris Beams
26  */
27 public final class RefreshableTargetSourceTests {
28 
29 	/**
30 	 * Test what happens when checking for refresh but not refreshing object.
31 	 */
32 	@Test
testRefreshCheckWithNonRefresh()33 	public void testRefreshCheckWithNonRefresh() throws Exception {
34 		CountingRefreshableTargetSource ts = new CountingRefreshableTargetSource();
35 		ts.setRefreshCheckDelay(0);
36 
37 		Object a = ts.getTarget();
38 		Thread.sleep(1);
39 		Object b = ts.getTarget();
40 
41 		assertEquals("Should be one call to freshTarget to get initial target", 1, ts.getCallCount());
42 		assertSame("Returned objects should be the same - no refresh should occur", a, b);
43 	}
44 
45 	/**
46 	 * Test what happens when checking for refresh and refresh occurs.
47 	 */
48 	@Test
testRefreshCheckWithRefresh()49 	public void testRefreshCheckWithRefresh() throws Exception {
50 		CountingRefreshableTargetSource ts = new CountingRefreshableTargetSource(true);
51 		ts.setRefreshCheckDelay(0);
52 
53 		Object a = ts.getTarget();
54 		Thread.sleep(100);
55 		Object b = ts.getTarget();
56 
57 		assertEquals("Should have called freshTarget twice", 2, ts.getCallCount());
58 		assertNotSame("Should be different objects", a, b);
59 	}
60 
61 	/**
62 	 * Test what happens when no refresh occurs.
63 	 */
64 	@Test
testWithNoRefreshCheck()65 	public void testWithNoRefreshCheck() throws Exception {
66 		CountingRefreshableTargetSource ts = new CountingRefreshableTargetSource(true);
67 		ts.setRefreshCheckDelay(-1);
68 
69 		Object a = ts.getTarget();
70 		Object b = ts.getTarget();
71 
72 		assertEquals("Refresh target should only be called once", 1, ts.getCallCount());
73 		assertSame("Objects should be the same - refresh check delay not elapsed", a, b);
74 	}
75 
76 	@Test
testRefreshOverTime()77 	public void testRefreshOverTime() throws Exception {
78 		CountingRefreshableTargetSource ts = new CountingRefreshableTargetSource(true);
79 		ts.setRefreshCheckDelay(100);
80 
81 		Object a = ts.getTarget();
82 		Object b = ts.getTarget();
83 		assertEquals("Objects should be same", a, b);
84 
85 		Thread.sleep(50);
86 
87 		Object c = ts.getTarget();
88 		assertEquals("A and C should be same", a, c);
89 
90 		Thread.sleep(60);
91 
92 		Object d = ts.getTarget();
93 		assertNotNull("D should not be null", d);
94 		assertFalse("A and D should not be equal", a.equals(d));
95 
96 		Object e = ts.getTarget();
97 		assertEquals("D and E should be equal", d, e);
98 
99 		Thread.sleep(110);
100 
101 		Object f = ts.getTarget();
102 		assertFalse("E and F should be different", e.equals(f));
103 	}
104 
105 
106 	private static class CountingRefreshableTargetSource extends AbstractRefreshableTargetSource {
107 
108 		private int callCount;
109 
110 		private boolean requiresRefresh;
111 
CountingRefreshableTargetSource()112 		public CountingRefreshableTargetSource() {
113 		}
114 
CountingRefreshableTargetSource(boolean requiresRefresh)115 		public CountingRefreshableTargetSource(boolean requiresRefresh) {
116 			this.requiresRefresh = requiresRefresh;
117 		}
118 
freshTarget()119 		protected Object freshTarget() {
120 			this.callCount++;
121 			return new Object();
122 		}
123 
getCallCount()124 		public int getCallCount() {
125 			return this.callCount;
126 		}
127 
requiresRefresh()128 		protected boolean requiresRefresh() {
129 			return this.requiresRefresh;
130 		}
131 	}
132 
133 }
134