18
18
19
19
import com .optimizely .ab .android .shared .Client ;
20
20
21
+ import junit .framework .Assert ;
22
+
21
23
import org .junit .Before ;
22
24
import org .junit .Test ;
23
25
import org .junit .runner .RunWith ;
24
26
import org .junit .runners .JUnit4 ;
25
27
import org .mockito .ArgumentCaptor ;
28
+ import org .mockito .invocation .InvocationOnMock ;
29
+ import org .mockito .stubbing .Answer ;
26
30
import org .slf4j .Logger ;
27
31
28
32
import java .io .IOException ;
29
33
import java .net .HttpURLConnection ;
30
34
import java .net .MalformedURLException ;
31
35
import java .net .URL ;
36
+ import java .net .URLConnection ;
32
37
33
38
import static junit .framework .Assert .assertTrue ;
34
39
import static org .junit .Assert .assertEquals ;
38
43
import static org .mockito .Matchers .eq ;
39
44
import static org .mockito .Mockito .doThrow ;
40
45
import static org .mockito .Mockito .mock ;
46
+ import static org .mockito .Mockito .times ;
41
47
import static org .mockito .Mockito .verify ;
42
48
import static org .mockito .Mockito .when ;
43
49
@@ -73,8 +79,8 @@ public void request200() throws IOException {
73
79
ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
74
80
ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
75
81
verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
76
- assertEquals (Integer .valueOf (2 ), captor2 .getValue ());
77
- assertEquals (Integer .valueOf (3 ), captor3 .getValue ());
82
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
83
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_RETRIES_POWER ), captor3 .getValue ());
78
84
Object response = captor1 .getValue ().execute ();
79
85
assertTrue (String .class .isInstance (response ));
80
86
assertEquals ("{}" , response );
@@ -85,6 +91,115 @@ public void request200() throws IOException {
85
91
verify (urlConnection ).disconnect ();
86
92
}
87
93
94
+ /**
95
+ * testLastModified - This is a test to see if given two projects, the last modified for datafile download is project specific.
96
+ * Two URLs url1 and url2 are both datafile urls, url1 is requested from the data client twice, while url2 is only asked for once.
97
+ * The first time the last modified is 0 and the second time, if it is non-zero, then it is the current last modified and a 304 is returned.
98
+ *
99
+ * @throws IOException
100
+ */
101
+ @ Test
102
+ public void testLastModified () throws IOException {
103
+ final URL url1 = new URL (DatafileService .getDatafileUrl ("1" ));
104
+ final URL url2 = new URL (DatafileService .getDatafileUrl ("2" ));
105
+ HttpURLConnection urlConnection2 = mock (HttpURLConnection .class );
106
+ when (urlConnection .getURL ()).thenReturn (url1 );
107
+ when (urlConnection2 .getURL ()).thenReturn (url2 );
108
+ when (urlConnection .getLastModified ()).thenReturn (0L );
109
+ when (urlConnection2 .getLastModified ()).thenReturn (0L );
110
+ when (client .openConnection (url1 )).thenReturn (urlConnection );
111
+ Answer <Integer > answer = new Answer <Integer >() {
112
+ public Integer answer (InvocationOnMock invocation ) throws Throwable {
113
+ HttpURLConnection connection = (HttpURLConnection ) invocation .getMock ();
114
+ URL url = connection .getURL ();
115
+ if (url == url1 ) {
116
+ if (connection .getLastModified () == 0L ) {
117
+ when (connection .getLastModified ()).thenReturn (300L );
118
+ return 200 ;
119
+ }
120
+ else {
121
+ assertEquals (connection .getLastModified (), 300L );
122
+ return 304 ;
123
+ }
124
+ }
125
+ else if (url == url2 ) {
126
+ if (connection .getLastModified () == 0L ) {
127
+ when (connection .getLastModified ()).thenReturn (200L );
128
+ return 200 ;
129
+ }
130
+ else {
131
+ assertEquals (connection .getLastModified (), 200L );
132
+ return 304 ;
133
+ }
134
+ }
135
+ //Object[] arguments = invocation.getArguments();
136
+ //String string = (String) arguments[0];
137
+ return 0 ;
138
+ }
139
+ };
140
+
141
+ when (urlConnection .getResponseCode ()).thenAnswer (answer );
142
+ when (urlConnection2 .getResponseCode ()).thenAnswer (answer );
143
+
144
+ when (client .openConnection (url2 )).thenReturn (urlConnection2 );
145
+ when (client .readStream (urlConnection )).thenReturn ("{}" );
146
+ when (client .readStream (urlConnection2 )).thenReturn ("{}" );
147
+
148
+ // first call returns the project file {}
149
+ datafileClient .request (url1 .toString ());
150
+
151
+ ArgumentCaptor <Client .Request > captor1 = ArgumentCaptor .forClass (Client .Request .class );
152
+ ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
153
+ ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
154
+ verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
155
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
156
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_RETRIES_POWER ), captor3 .getValue ());
157
+ Object response = captor1 .getValue ().execute ();
158
+ assertTrue (String .class .isInstance (response ));
159
+ assertEquals ("{}" , response );
160
+
161
+ verify (logger ).info ("Requesting data file from {}" , url1 );
162
+ verify (client ).saveLastModified (urlConnection );
163
+ verify (client ).readStream (urlConnection );
164
+ verify (urlConnection ).disconnect ();
165
+
166
+ // second call returns 304 so the response is a empty string.
167
+ datafileClient .request (url1 .toString ());
168
+
169
+ captor1 = ArgumentCaptor .forClass (Client .Request .class );
170
+ captor2 = ArgumentCaptor .forClass (Integer .class );
171
+ captor3 = ArgumentCaptor .forClass (Integer .class );
172
+ verify (client , times (2 )).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
173
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
174
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_RETRIES_POWER ), captor3 .getValue ());
175
+ response = captor1 .getValue ().execute ();
176
+ assertTrue (String .class .isInstance (response ));
177
+ assertEquals ("" , response );
178
+
179
+ verify (logger ).info ("Data file has not been modified on the cdn" );
180
+ verify (urlConnection , times (2 )).disconnect ();
181
+
182
+ datafileClient .request (url2 .toString ());
183
+
184
+ captor1 = ArgumentCaptor .forClass (Client .Request .class );
185
+ captor2 = ArgumentCaptor .forClass (Integer .class );
186
+ captor3 = ArgumentCaptor .forClass (Integer .class );
187
+ verify (client , times (3 )).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
188
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
189
+ assertEquals (Integer .valueOf (DatafileClient .REQUEST_RETRIES_POWER ), captor3 .getValue ());
190
+ response = captor1 .getValue ().execute ();
191
+ assertTrue (String .class .isInstance (response ));
192
+ assertEquals ("{}" , response );
193
+
194
+ verify (logger , times (2 )).info ("Requesting data file from {}" , url1 );
195
+ verify (client ).saveLastModified (urlConnection2 );
196
+ verify (client ).readStream (urlConnection2 );
197
+ verify (urlConnection2 ).disconnect ();
198
+
199
+
200
+ }
201
+
202
+
88
203
@ Test
89
204
public void request201 () throws IOException {
90
205
URL url = new URL (DatafileService .getDatafileUrl ("1" ));
@@ -98,8 +213,8 @@ public void request201() throws IOException {
98
213
ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
99
214
ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
100
215
verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
101
- assertEquals (Integer .valueOf (2 ), captor2 .getValue ());
102
- assertEquals (Integer .valueOf (3 ), captor3 .getValue ());
216
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
217
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_RETRIES_POWER ), captor3 .getValue ());
103
218
Object response = captor1 .getValue ().execute ();
104
219
assertTrue (String .class .isInstance (response ));
105
220
assertEquals ("{}" , response );
@@ -123,8 +238,8 @@ public void request299() throws IOException {
123
238
ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
124
239
ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
125
240
verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
126
- assertEquals (Integer .valueOf (2 ), captor2 .getValue ());
127
- assertEquals (Integer .valueOf (3 ), captor3 .getValue ());
241
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
242
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_RETRIES_POWER ), captor3 .getValue ());
128
243
Object response = captor1 .getValue ().execute ();
129
244
assertTrue (String .class .isInstance (response ));
130
245
assertEquals ("{}" , response );
@@ -146,8 +261,8 @@ public void request300() throws IOException {
146
261
ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
147
262
ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
148
263
verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
149
- assertEquals (Integer .valueOf (2 ), captor2 .getValue ());
150
- assertEquals (Integer .valueOf (3 ), captor3 .getValue ());
264
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
265
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_RETRIES_POWER ), captor3 .getValue ());
151
266
Object response = captor1 .getValue ().execute ();
152
267
assertNull (response );
153
268
@@ -167,8 +282,8 @@ public void handlesIOException() throws IOException {
167
282
ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
168
283
ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
169
284
verify (client ).execute (captor1 .capture (), captor2 .capture (), captor3 .capture ());
170
- assertEquals (Integer .valueOf (2 ), captor2 .getValue ());
171
- assertEquals (Integer .valueOf (3 ), captor3 .getValue ());
285
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), captor2 .getValue ());
286
+ assertEquals (Integer .valueOf (DatafileClient . REQUEST_RETRIES_POWER ), captor3 .getValue ());
172
287
Object response = captor1 .getValue ().execute ();
173
288
assertNull (response );
174
289
@@ -180,14 +295,14 @@ public void handlesIOException() throws IOException {
180
295
@ Test
181
296
public void handlesNullResponse () throws MalformedURLException {
182
297
URL url = new URL (DatafileService .getDatafileUrl ("1" ));
183
- when (client .execute (any (Client .Request .class ), eq (2 ), eq (3 ))).thenReturn (null );
298
+ when (client .execute (any (Client .Request .class ), eq (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), eq (DatafileClient . REQUEST_RETRIES_POWER ))).thenReturn (null );
184
299
assertNull (datafileClient .request (url .toString ()));
185
300
}
186
301
187
302
@ Test
188
303
public void handlesEmptyStringResponse () throws MalformedURLException {
189
304
URL url = new URL (DatafileService .getDatafileUrl ("1" ));
190
- when (client .execute (any (Client .Request .class ), eq (2 ), eq (3 ))).thenReturn ("" );
305
+ when (client .execute (any (Client .Request .class ), eq (DatafileClient . REQUEST_BACKOFF_TIMEOUT ), eq (DatafileClient . REQUEST_RETRIES_POWER ))).thenReturn ("" );
191
306
assertEquals ("" , datafileClient .request (url .toString ()));
192
307
}
193
308
}
0 commit comments