|
12 | 12 | import org.openqa.selenium.WebDriver; |
13 | 13 | import org.openqa.selenium.WebElement; |
14 | 14 |
|
| 15 | +import java.lang.reflect.Field; |
15 | 16 | import java.util.ArrayList; |
16 | 17 | import java.util.List; |
| 18 | +import java.util.Map; |
17 | 19 | import java.util.stream.Stream; |
18 | 20 |
|
19 | 21 | import static java.util.stream.Collectors.toList; |
20 | 22 | import static org.hamcrest.MatcherAssert.assertThat; |
21 | 23 | import static org.hamcrest.Matchers.contains; |
22 | 24 | import static org.hamcrest.Matchers.equalTo; |
| 25 | +import static org.hamcrest.Matchers.lessThan; |
23 | 26 | import static org.openqa.selenium.support.PageFactory.initElements; |
24 | 27 |
|
25 | 28 |
|
26 | 29 | @SuppressWarnings({"unchecked", "unused"}) |
27 | 30 | public class CombinedWidgetTest { |
28 | 31 |
|
| 32 | + /** |
| 33 | + * Based on how many Proxy Classes are created during this test class, |
| 34 | + * this number is used to determine if the cache is being purged correctly between tests. |
| 35 | + */ |
| 36 | + private static final int THRESHOLD_SIZE = 50; |
| 37 | + |
29 | 38 | /** |
30 | 39 | * Test data generation. |
31 | 40 | * |
@@ -57,6 +66,7 @@ public static Stream<Arguments> data() { |
57 | 66 | @ParameterizedTest |
58 | 67 | @MethodSource("data") |
59 | 68 | void checkThatWidgetsAreCreatedCorrectly(AbstractApp app, WebDriver driver, Class<?> widgetClass) { |
| 69 | + assertProxyClassCacheGrowth(); |
60 | 70 | initElements(new AppiumFieldDecorator(driver), app); |
61 | 71 | assertThat("Expected widget class was " + widgetClass.getName(), |
62 | 72 | app.getWidget().getSubWidget().getSelfReference().getClass(), |
@@ -161,4 +171,32 @@ public List<PartiallyCombinedWidget> getWidgets() { |
161 | 171 | return multipleWidgets; |
162 | 172 | } |
163 | 173 | } |
| 174 | + |
| 175 | + |
| 176 | + /** |
| 177 | + * Assert proxy class cache growth for this test class. |
| 178 | + * The (@link io.appium.java_client.proxy.Helpers#CACHED_PROXY_CLASSES) should be populated during these tests. |
| 179 | + * Prior to the Caching issue being resolved |
| 180 | + * - the CACHED_PROXY_CLASSES would grow indefinitely, resulting in an Out Of Memory exception. |
| 181 | + * - this ParameterizedTest would have the CACHED_PROXY_CLASSES grow to 266 entries. |
| 182 | + */ |
| 183 | + private void assertProxyClassCacheGrowth() { |
| 184 | + System.gc(); //Trying to force a collection for more accurate check numbers |
| 185 | + assertThat( |
| 186 | + "Proxy Class Cache threshold is " + THRESHOLD_SIZE, |
| 187 | + getCachedProxyClassesSize(), |
| 188 | + lessThan(THRESHOLD_SIZE) |
| 189 | + ); |
| 190 | + } |
| 191 | + |
| 192 | + private int getCachedProxyClassesSize() { |
| 193 | + try { |
| 194 | + Field cpc = Class.forName("io.appium.java_client.proxy.Helpers").getDeclaredField("CACHED_PROXY_CLASSES"); |
| 195 | + cpc.setAccessible(true); |
| 196 | + Map<?, ?> cachedProxyClasses = (Map<?, ?>) cpc.get(null); |
| 197 | + return cachedProxyClasses.size(); |
| 198 | + } catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e) { |
| 199 | + throw new RuntimeException(e); |
| 200 | + } |
| 201 | + } |
164 | 202 | } |
0 commit comments