1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package com.jcabi.github.wire;
31
32 import com.jcabi.github.RandomPort;
33 import com.jcabi.http.mock.MkAnswer;
34 import com.jcabi.http.mock.MkContainer;
35 import com.jcabi.http.mock.MkGrizzlyContainer;
36 import com.jcabi.http.request.FakeRequest;
37 import com.jcabi.http.request.JdkRequest;
38 import com.jcabi.http.response.RestResponse;
39 import java.io.IOException;
40 import java.net.HttpURLConnection;
41 import java.util.concurrent.TimeUnit;
42 import org.hamcrest.MatcherAssert;
43 import org.hamcrest.Matchers;
44 import org.junit.Rule;
45 import org.junit.Test;
46
47
48
49
50
51
52
53
54
55 public final class RetryCarefulWireTest {
56
57
58
59 private static final String OK = "OK";
60
61
62
63 private static final String REMAINING_HEADER = "X-RateLimit-Remaining";
64
65
66
67
68 @Rule
69 public final transient RandomPort resource = new RandomPort();
70
71
72
73
74
75
76 @Test
77 public void makesMultipleRequestsAndWaitUntilReset() throws Exception {
78 final int threshold = 10;
79
80 final long reset = TimeUnit.MILLISECONDS
81 .toSeconds(System.currentTimeMillis()) + 5L;
82 final MkContainer container = new MkGrizzlyContainer()
83 .next(new MkAnswer.Simple(HttpURLConnection.HTTP_INTERNAL_ERROR))
84 .next(new MkAnswer.Simple(HttpURLConnection.HTTP_INTERNAL_ERROR))
85 .next(new MkAnswer.Simple(HttpURLConnection.HTTP_OK)
86 .withHeader(REMAINING_HEADER, "9")
87 .withHeader("X-RateLimit-Reset", String.valueOf(reset))
88 )
89 .start(this.resource.port());
90 new JdkRequest(container.home())
91 .through(RetryCarefulWire.class, threshold)
92 .fetch()
93 .as(RestResponse.class)
94 .assertStatus(HttpURLConnection.HTTP_OK);
95 final long now = TimeUnit.MILLISECONDS
96 .toSeconds(System.currentTimeMillis());
97 MatcherAssert.assertThat(now, Matchers.greaterThanOrEqualTo(reset));
98 container.stop();
99 }
100
101
102
103
104
105 @Test
106 public void tolerateMissingRateLimitRemainingHeader() throws IOException {
107 final int threshold = 11;
108
109 new FakeRequest()
110 .withStatus(HttpURLConnection.HTTP_OK)
111 .withReason(OK)
112 .through(RetryCarefulWire.class, threshold)
113 .fetch();
114 MatcherAssert.assertThat(
115 "Did not crash when X-RateLimit-Remaining header was absent",
116 true
117 );
118 }
119
120
121
122
123
124 @Test
125 public void tolerateMissingRateLimitResetHeader() throws IOException {
126 final int threshold = 8;
127
128 new FakeRequest()
129 .withStatus(HttpURLConnection.HTTP_OK)
130 .withReason(OK)
131 .withHeader(REMAINING_HEADER, "7")
132 .through(RetryCarefulWire.class, threshold)
133 .fetch();
134 MatcherAssert.assertThat(
135 "Did not crash when X-RateLimit-Reset header was absent",
136 true
137 );
138 }
139 }