You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixed#657: Turn SignalingClient into normal class from singleton. Fixed#658: RCConnection localMediaType not properly set in audio call. Fixed#659: Document Integration Testing facilities. Fixed#655: Research and integrate/develop base facilities for asynchronous integration tests for SDK
Copy file name to clipboardExpand all lines: Examples/restcomm-olympus/app/src/androidTest/java/org/restcomm/android/olympus/IntegrationTests.java
+30-33Lines changed: 30 additions & 33 deletions
Original file line number
Diff line number
Diff line change
@@ -39,7 +39,7 @@
39
39
40
40
@RunWith(AndroidJUnit4.class)
41
41
/**
42
-
* This class implements instrumented (i.e. on Device) integration tests facilities for the Restcomm Android SDK using JUnit4. Instrumented tests
42
+
* This class implements instrumented integration test facilities (i.e. that run on device) for the Restcomm Android SDK using JUnit4. Instrumented tests
43
43
* are more complex and more time consuming, but they need to be instrumented if we are to get realistic results. Integration tests are not meant to
44
44
* replace UI or Unit tests, but to complement them by providing a way to really test our SDK's API top to bottom.
45
45
*
@@ -53,26 +53,42 @@
53
53
* Design and synchronization considerations
54
54
*
55
55
* The IT facilities are desined so that there are 3 threads involved in the tests (separate media threads are not relevant to this so they are kept out):
56
-
* - The testing thread, where test cases run
57
-
* - The API/Service thread where RCDevice/RCConnection calls are made, and relative callbacks are invoked
56
+
* - The testing thread, where test cases run; this is the default thread where you test code runs unless told otherwise
57
+
* - The API/Service thread where RCDevice/RCConnection calls are made, and relative callbacks are invoked (i.e. RCDevice.onInitialized())
58
58
* - The Signaling thread that runs JAIN SIP user code and stack
59
59
*
60
60
* The reason we are using this setup is so that the testing thread that runs Awaitility framework (that provides facilities to wait
61
-
* on various conditions) needs to be on a separate thread than API thread otherwise when API thread is blocked waiting for messages from Signaling thread
61
+
* on various conditions) needs to be on a separate thread than API/Service thread otherwise when API thread is blocked waiting for messages from Signaling thread
62
62
* the Awaitility framework wouldn't have a way to wait on conditions properly and the whole thing would break. Also, we want the testing thread to
63
63
* be separate so that it's not affected by any timing issues on ANRs that the API thread might encounter. Finally we need to be able to write our tests
64
-
* linearly so that they are easy to read and understand. So even though we could potentially keep Awaitility out and just use a single thread for testing and API
64
+
* linearly so that they are easy to read and extend. So even though we could potentially keep Awaitility out and just use a single thread for testing and API
65
65
* by adding more logic in the callback, the whole thing would become a mess as we'd have to keep state all over the place
66
66
*
67
-
* TODO: describe how Handlers & HandlerThreads are used, and why. Also describe how to avoid threading issues by always using the Main Looper for API thread
67
+
* Adding/Extending an integration Test
68
68
*
69
-
* Extending the Integration Tests
69
+
* Each integration test needs to do the following (please check deviceInitialize_Valid() test case for more details):
70
+
* - Bind to the RCDevice Android Service and wait until it is connected using Awaitility condition variable (i.e. serviceConnected). This happens in the current (i.e. testing) thread
71
+
* - Create an Android Handler and associate it with the Main Looper thread so that you can post work for it easily and linearly. Important: the Main Looper thread
72
+
* is by default SEPARATE from the test thread, and the reason we use this Main Looper Thread specifically (instead of for example creating a new HandlerThread) is that inside
73
+
* the API/Service this is the thread we explicitly use in some occasions to refer to the Service thread, so we need to stay consistent. For example the first thing
74
+
* you will want to do in a test case is call RCDevice.initialize(). This needs to happen inside the API/Service thread
75
+
* - Wait for RCDevice to be initialized on the testing thread. To do this you need to wait on an Awaitility condition variable (i.e. deviceInitialized) which is set when RCDevice.onInitialized() is called
76
+
* on the API/Service thread.
77
+
* - Assert that all is good by inspecting the context. Context is a HashMap that gets filled from the API/Service thread when a response is received with any information that we might need
78
+
* like RCDevice object or status code
79
+
* - After that you can continue posting actions in the API/Service thread, waiting for responses in the testing thread and asserting results sequentially.
70
80
*
71
-
* TODO: describe the assumptions made about the tests, like conditions variables and context, as well as synchronization between test & API threads that is not really implemented
81
+
* Note that in the future if needed, we could potentially use another thread for API/Service instead of Main Looper thread. But if we do that we need to make sure to fix code
82
+
* inside API/Service so that it doesn't use .getMainLooper() as it does right now. Otherwise we are bound to have synchronization issues.
83
+
*
84
+
* Notice that so far synchronization between test & API threads is not really implemented. So far it hasn't caused us any issues in the sense that context is not read by the test thread
85
+
* until condition variable is set by the API/Service thread, which means that API/Service thread has finished writing it. Still the condition variable is accessed by both API/Service
86
+
* thread and test thread, so we might need to remedy that at some point.
72
87
*
73
88
* Additional notes
74
89
*
75
-
* TODO: describe the issues with ServiceTestRule and why we removed it
90
+
* Originally we used a ServiceTestRule to help us in waiting until the Android Service is ready, but we encountered some issues so we fell back to using Awaitility since it provides
91
+
* pretty nice facilities on waiting for condition.
0 commit comments