|
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