1818
1919import com .optimizely .ab .android .shared .Client ;
2020
21+ import junit .framework .Assert ;
22+
2123import org .junit .Before ;
2224import org .junit .Test ;
2325import org .junit .runner .RunWith ;
2426import org .junit .runners .JUnit4 ;
2527import org .mockito .ArgumentCaptor ;
28+ import org .mockito .invocation .InvocationOnMock ;
29+ import org .mockito .stubbing .Answer ;
2630import org .slf4j .Logger ;
2731
2832import java .io .IOException ;
2933import java .net .HttpURLConnection ;
3034import java .net .MalformedURLException ;
3135import java .net .URL ;
36+ import java .net .URLConnection ;
3237
3338import static junit .framework .Assert .assertTrue ;
3439import static org .junit .Assert .assertEquals ;
3843import static org .mockito .Matchers .eq ;
3944import static org .mockito .Mockito .doThrow ;
4045import static org .mockito .Mockito .mock ;
46+ import static org .mockito .Mockito .times ;
4147import static org .mockito .Mockito .verify ;
4248import static org .mockito .Mockito .when ;
4349
@@ -73,8 +79,8 @@ public void request200() throws IOException {
7379 ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
7480 ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
7581 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 ());
7884 Object response = captor1 .getValue ().execute ();
7985 assertTrue (String .class .isInstance (response ));
8086 assertEquals ("{}" , response );
@@ -85,6 +91,115 @@ public void request200() throws IOException {
8591 verify (urlConnection ).disconnect ();
8692 }
8793
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+
88203 @ Test
89204 public void request201 () throws IOException {
90205 URL url = new URL (DatafileService .getDatafileUrl ("1" ));
@@ -98,8 +213,8 @@ public void request201() throws IOException {
98213 ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
99214 ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
100215 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 ());
103218 Object response = captor1 .getValue ().execute ();
104219 assertTrue (String .class .isInstance (response ));
105220 assertEquals ("{}" , response );
@@ -123,8 +238,8 @@ public void request299() throws IOException {
123238 ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
124239 ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
125240 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 ());
128243 Object response = captor1 .getValue ().execute ();
129244 assertTrue (String .class .isInstance (response ));
130245 assertEquals ("{}" , response );
@@ -146,8 +261,8 @@ public void request300() throws IOException {
146261 ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
147262 ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
148263 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 ());
151266 Object response = captor1 .getValue ().execute ();
152267 assertNull (response );
153268
@@ -167,8 +282,8 @@ public void handlesIOException() throws IOException {
167282 ArgumentCaptor <Integer > captor2 = ArgumentCaptor .forClass (Integer .class );
168283 ArgumentCaptor <Integer > captor3 = ArgumentCaptor .forClass (Integer .class );
169284 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 ());
172287 Object response = captor1 .getValue ().execute ();
173288 assertNull (response );
174289
@@ -180,14 +295,14 @@ public void handlesIOException() throws IOException {
180295 @ Test
181296 public void handlesNullResponse () throws MalformedURLException {
182297 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 );
184299 assertNull (datafileClient .request (url .toString ()));
185300 }
186301
187302 @ Test
188303 public void handlesEmptyStringResponse () throws MalformedURLException {
189304 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 ("" );
191306 assertEquals ("" , datafileClient .request (url .toString ()));
192307 }
193308}
0 commit comments