blob: 89a0e4d0dea38882a32e2f4ba850890f7ddea8d9 [file] [log] [blame]
Rahul Ravikumar056b21a2019-01-28 12:56:21 -08001/*
2 * Copyright 2019 The Android Open Source Project
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
17package androidx.work.impl.background.gcm
18
19import androidx.test.ext.junit.runners.AndroidJUnit4
20import androidx.test.filters.SdkSuppress
21import androidx.test.filters.SmallTest
22import androidx.work.Constraints
23import androidx.work.NetworkType
24import androidx.work.OneTimeWorkRequestBuilder
25import androidx.work.PeriodicWorkRequestBuilder
26import androidx.work.impl.WorkManagerImpl
27import androidx.work.impl.background.gcm.GcmTaskConverter.EXECUTION_WINDOW_SIZE_IN_SECONDS
28import com.google.android.gms.gcm.Task
29import org.hamcrest.Matchers.greaterThan
Rahul Ravikumar413a58d2019-07-16 15:47:58 -070030import org.hamcrest.Matchers.lessThanOrEqualTo
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080031import org.junit.Assert.assertEquals
32import org.junit.Assert.assertThat
33import org.junit.Before
34import org.junit.Test
35import org.junit.runner.RunWith
36import org.mockito.Mockito.`when`
37import org.mockito.Mockito.spy
38import java.util.concurrent.TimeUnit
39
40@RunWith(AndroidJUnit4::class)
41@SmallTest
42class GcmTaskConverterTest {
43
44 lateinit var mTaskConverter: GcmTaskConverter
45
46 @Before
47 fun setUp() {
48 mTaskConverter = spy(GcmTaskConverter())
49 }
50
51 @Test
52 fun testOneTimeRequest_noInitialDelay() {
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070053 val now = System.currentTimeMillis()
54 `when`(mTaskConverter.now()).thenReturn(now)
55
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080056 val request = OneTimeWorkRequestBuilder<TestWorker>().build()
57 val task = mTaskConverter.convert(request.workSpec)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070058
59 val expected = request.workSpec.calculateNextRunTime()
60 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -070061 val deltaStart = task.windowStart - offset
62 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070063
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080064 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
65 assertEquals(task.isPersisted, false)
66 assertEquals(task.isUpdateCurrent, true)
67 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
68 assertEquals(task.requiresCharging, false)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -070069 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -070070 assertThat(deltaStart, lessThanOrEqualTo(1L))
71 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080072 }
73
74 @Test
75 fun testOneTimeRequest_noInitialDelay_withConstraintNetworkConnected() {
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070076 val now = System.currentTimeMillis()
77 `when`(mTaskConverter.now()).thenReturn(now)
78
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080079 val constraints = Constraints.Builder()
80 .setRequiredNetworkType(NetworkType.METERED)
81 .setRequiresCharging(true)
82 .build()
83
84 val request = OneTimeWorkRequestBuilder<TestWorker>()
85 .setConstraints(constraints)
86 .build()
87
88 val task = mTaskConverter.convert(request.workSpec)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070089 val expected = request.workSpec.calculateNextRunTime()
90 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -070091 val deltaStart = task.windowStart - offset
92 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -070093
Rahul Ravikumar056b21a2019-01-28 12:56:21 -080094 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
95 assertEquals(task.isPersisted, false)
96 assertEquals(task.isUpdateCurrent, true)
97 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_CONNECTED)
98 assertEquals(task.requiresCharging, true)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -070099 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700100 assertThat(deltaStart, lessThanOrEqualTo(1L))
101 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800102 }
103
104 @Test
105 fun testOneTimeRequest_noInitialDelay_withConstraintNetworkUnMetered() {
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -0700106 val now = System.currentTimeMillis()
107 `when`(mTaskConverter.now()).thenReturn(now)
108
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800109 val constraints = Constraints.Builder()
110 .setRequiredNetworkType(NetworkType.UNMETERED)
111 .build()
112
113 val request = OneTimeWorkRequestBuilder<TestWorker>()
114 .setConstraints(constraints)
115 .build()
116
117 val task = mTaskConverter.convert(request.workSpec)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -0700118 val expected = request.workSpec.calculateNextRunTime()
119 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700120 val deltaStart = task.windowStart - offset
121 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar0dfc7da2019-06-18 13:45:26 -0700122
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800123 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
124 assertEquals(task.isPersisted, false)
125 assertEquals(task.isUpdateCurrent, true)
126 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_UNMETERED)
127 assertEquals(task.requiresCharging, false)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700128 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700129 assertThat(deltaStart, lessThanOrEqualTo(1L))
130 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800131 }
132
133 @Test
134 fun testOneTimeRequest_hasInitialDelay() {
135 val initialDelay = 10L
136 val now = System.currentTimeMillis()
137 `when`(mTaskConverter.now()).thenReturn(now)
138
139 val request = OneTimeWorkRequestBuilder<TestWorker>()
140 .setInitialDelay(initialDelay, TimeUnit.SECONDS)
141 .build()
142
143 val task = mTaskConverter.convert(request.workSpec)
144 val expected = request.workSpec.calculateNextRunTime()
145 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700146 val deltaStart = task.windowStart - offset
147 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800148
149 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
150 assertEquals(task.isPersisted, false)
151 assertEquals(task.isUpdateCurrent, true)
152 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
153 assertEquals(task.requiresCharging, false)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700154 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700155 assertThat(deltaStart, lessThanOrEqualTo(1L))
156 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800157 }
158
159 @Test
160 fun testOneTimeWorkRequest_backedOff() {
161 val now = System.currentTimeMillis()
162 `when`(mTaskConverter.now()).thenReturn(now)
163
164 val request = OneTimeWorkRequestBuilder<TestWorker>()
165 .setInitialRunAttemptCount(1)
166 .build()
167
168 val workSpec = request.workSpec
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700169 val task = mTaskConverter.convert(request.workSpec)
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800170 val expected = workSpec.calculateNextRunTime()
171 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700172 val deltaStart = task.windowStart - offset
173 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800174
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800175 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
176 assertEquals(task.isPersisted, false)
177 assertEquals(task.isUpdateCurrent, true)
178 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
179 assertEquals(task.requiresCharging, false)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700180 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700181 assertThat(deltaStart, lessThanOrEqualTo(1L))
182 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800183 }
184
185 @Test
186 @SdkSuppress(maxSdkVersion = WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL)
187 fun testPeriodicWorkRequest_firstRun() {
188 val now = System.currentTimeMillis()
189 `when`(mTaskConverter.now()).thenReturn(now)
190
191 val request = PeriodicWorkRequestBuilder<TestWorker>(15L, TimeUnit.MINUTES)
192 .build()
193
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700194 val task = mTaskConverter.convert(request.workSpec)
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800195 val expected = request.workSpec.calculateNextRunTime()
196 val offset = offset(expected, now)
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700197 val deltaStart = task.windowStart - offset
198 val deltaEnd = task.windowEnd - (offset + EXECUTION_WINDOW_SIZE_IN_SECONDS)
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800199
200 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
201 assertEquals(task.isPersisted, false)
202 assertEquals(task.isUpdateCurrent, true)
203 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
204 assertEquals(task.requiresCharging, false)
Rahul Ravikumar413a58d2019-07-16 15:47:58 -0700205 // Account for time unit quantization errors
Rahul Ravikumar4a3549a2019-07-23 14:55:16 -0700206 assertThat(deltaStart, lessThanOrEqualTo(1L))
207 assertThat(deltaEnd, lessThanOrEqualTo(1L))
Rahul Ravikumar056b21a2019-01-28 12:56:21 -0800208 }
209
210 @Test
211 @SdkSuppress(maxSdkVersion = WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL)
212 fun testPeriodicWorkRequest_withFlex_firstRun() {
213 val request = PeriodicWorkRequestBuilder<TestWorker>(
214 15L, TimeUnit.MINUTES, 5, TimeUnit.MINUTES
215 ).build()
216
217 val task = mTaskConverter.convert(request.workSpec)
218 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
219 assertEquals(task.isPersisted, false)
220 assertEquals(task.isUpdateCurrent, true)
221 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
222 assertEquals(task.requiresCharging, false)
223 assertThat(task.windowStart, greaterThan(0L)) // should be in the future
224 }
225
226 @Test
227 @SdkSuppress(maxSdkVersion = WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL)
228 fun testPeriodicWorkRequest_withFlex_nextRun() {
229 val now = System.currentTimeMillis()
230 `when`(mTaskConverter.now()).thenReturn(now)
231
232 val request = PeriodicWorkRequestBuilder<TestWorker>(
233 15L, TimeUnit.MINUTES, 5, TimeUnit.MINUTES
234 ).build()
235
236 request.workSpec.periodStartTime = now
237 val expected = TimeUnit.MINUTES.toSeconds(15L)
238
239 val task = mTaskConverter.convert(request.workSpec)
240
241 assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
242 assertEquals(task.isPersisted, false)
243 assertEquals(task.isUpdateCurrent, true)
244 assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
245 assertEquals(task.requiresCharging, false)
246 assertEquals(task.windowStart, expected)
247 assertEquals(task.windowEnd, expected + EXECUTION_WINDOW_SIZE_IN_SECONDS)
248 }
249
250 private fun offset(expected: Long, now: Long): Long {
251 val delta = Math.max(expected - now, 0)
252 return TimeUnit.SECONDS.convert(delta, TimeUnit.MILLISECONDS)
253 }
254}