Skip to content

Commit 374c175

Browse files
committed
Use local httpbin to run tests
Fix com-lihaoyi#132 Start a local httpbin container to run tests against. Https requests are still using remote one since it's hard to setup local secure ssl. The requests using https are simple and during my tests I haven't seen any timeout.
1 parent beb5d26 commit 374c175

File tree

2 files changed

+63
-45
lines changed

2 files changed

+63
-45
lines changed

build.sc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ trait RequestsModule extends CrossScalaModule with PublishModule with Mima {
4040
object test extends ScalaTests with TestModule.Utest {
4141
def ivyDeps = Agg(
4242
ivy"com.lihaoyi::utest::0.7.10",
43-
ivy"com.lihaoyi::ujson::1.3.13"
43+
ivy"com.lihaoyi::ujson::1.3.13",
44+
ivy"com.dimafeng::testcontainers-scala-core:0.41.3"
4445
)
4546
}
4647
}

requests/test/src/requests/RequestTests.scala

Lines changed: 61 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
package requests
22

3+
import com.dimafeng.testcontainers.GenericContainer
4+
import org.testcontainers.containers.wait.strategy.Wait
35
import utest._
46
import ujson._
57

68
object RequestTests extends TestSuite{
9+
10+
val containerDef = GenericContainer.Def(
11+
"kennethreitz/httpbin",
12+
exposedPorts = Seq(80),
13+
waitStrategy = Wait.forHttp("/")
14+
)
15+
val container = containerDef.start()
16+
val localHttpbinHost = container.containerIpAddress
17+
val localHttpbin = s"${localHttpbinHost}:${container.mappedPort(80)}"
18+
19+
override def utestAfterAll(): Unit = {
20+
container.stop()
21+
}
22+
723
val tests = Tests{
824
test("matchingMethodWorks"){
925
val requesters = Seq(
@@ -13,18 +29,18 @@ object RequestTests extends TestSuite{
1329
requests.put
1430
)
1531

16-
for(protocol <- Seq("http", "https")){
32+
for(baseUrl <- Seq(s"http://$localHttpbin", "https://httpbin.org")){
1733
for(r <- requesters){
1834
for(r2 <- requesters){
19-
val res = r(s"$protocol://httpbin.org/${r2.verb.toLowerCase()}", check = false)
35+
val res = r(s"$baseUrl/${r2.verb.toLowerCase()}", check = false)
2036
if (r.verb == r2.verb) assert(res.statusCode == 200)
2137
else assert(res.statusCode == 405)
2238

2339
if (r.verb == r2.verb){
24-
val res = r(s"$protocol://httpbin.org/${r2.verb.toLowerCase()}")
40+
val res = r(s"$baseUrl/${r2.verb.toLowerCase()}")
2541
assert(res.statusCode == 200)
2642
}else intercept[RequestFailedException]{
27-
r(s"$protocol://httpbin.org/${r2.verb.toLowerCase()}")
43+
r(s"$baseUrl/${r2.verb.toLowerCase()}")
2844
}
2945
}
3046
}
@@ -34,26 +50,26 @@ object RequestTests extends TestSuite{
3450
test("params"){
3551
test("get"){
3652
// All in URL
37-
val res1 = requests.get("https://httpbin.org/get?hello=world&foo=baz").text()
53+
val res1 = requests.get(s"http://$localHttpbin/get?hello=world&foo=baz").text()
3854
assert(read(res1).obj("args") == Obj("foo" -> "baz", "hello" -> "world"))
3955

4056
// All in params
4157
val res2 = requests.get(
42-
"https://httpbin.org/get",
58+
s"http://$localHttpbin/get",
4359
params = Map("hello" -> "world", "foo" -> "baz")
4460
)
4561
assert(read(res2).obj("args") == Obj("foo" -> "baz", "hello" -> "world"))
4662

4763
// Mixed URL and params
4864
val res3 = requests.get(
49-
"https://httpbin.org/get?hello=world",
65+
s"http://$localHttpbin/get?hello=world",
5066
params = Map("foo" -> "baz")
5167
).text()
5268
assert(read(res3).obj("args") == Obj("foo" -> "baz", "hello" -> "world"))
5369

5470
// Needs escaping
5571
val res4 = requests.get(
56-
"https://httpbin.org/get?hello=world",
72+
s"http://$localHttpbin/get?hello=world",
5773
params = Map("++-- lol" -> " !@#$%")
5874
)
5975
assert(read(res4).obj("args") == Obj("++-- lol" -> " !@#$%", "hello" -> "world"))
@@ -63,7 +79,7 @@ object RequestTests extends TestSuite{
6379
test("multipart"){
6480
for(chunkedUpload <- Seq(true, false)) {
6581
val response = requests.post(
66-
"http://httpbin.org/post",
82+
s"http://$localHttpbin/post",
6783
data = MultiPart(
6884
MultiItem("file1", "Hello!".getBytes, "foo.txt"),
6985
MultiItem("file2", "Goodbye!")
@@ -79,76 +95,77 @@ object RequestTests extends TestSuite{
7995
test("cookies"){
8096
test("session"){
8197
val s = requests.Session(cookieValues = Map("hello" -> "world"))
82-
val res1 = s.get("https://httpbin.org/cookies").text().trim
98+
val res1 = s.get(s"http://$localHttpbin/cookies").text().trim
8399
assert(read(res1) == Obj("cookies" -> Obj("hello" -> "world")))
84-
s.get("https://httpbin.org/cookies/set?freeform=test")
85-
val res2 = s.get("https://httpbin.org/cookies").text().trim
100+
s.get(s"http://$localHttpbin/cookies/set?freeform=test")
101+
val res2 = s.get(s"http://$localHttpbin/cookies").text().trim
86102
assert(read(res2) == Obj("cookies" -> Obj("freeform" -> "test", "hello" -> "world")))
87103
}
88104
test("raw"){
89-
val res1 = requests.get("https://httpbin.org/cookies").text().trim
105+
val res1 = requests.get(s"http://$localHttpbin/cookies").text().trim
90106
assert(read(res1) == Obj("cookies" -> Obj()))
91-
requests.get("https://httpbin.org/cookies/set?freeform=test")
92-
val res2 = requests.get("https://httpbin.org/cookies").text().trim
107+
requests.get(s"http://$localHttpbin/cookies/set?freeform=test")
108+
val res2 = requests.get(s"http://$localHttpbin/cookies").text().trim
93109
assert(read(res2) == Obj("cookies" -> Obj()))
94110
}
95111
test("space"){
96112
val s = requests.Session(cookieValues = Map("hello" -> "hello, world"))
97-
val res1 = s.get("https://httpbin.org/cookies").text().trim
113+
val res1 = s.get(s"http://$localHttpbin/cookies").text().trim
98114
assert(read(res1) == Obj("cookies" -> Obj("hello" -> "hello, world")))
99-
s.get("https://httpbin.org/cookies/set?freeform=test+test")
100-
val res2 = s.get("https://httpbin.org/cookies").text().trim
115+
s.get(s"http://$localHttpbin/cookies/set?freeform=test+test")
116+
val res2 = s.get(s"http://$localHttpbin/cookies").text().trim
101117
assert(read(res2) == Obj("cookies" -> Obj("freeform" -> "test test", "hello" -> "hello, world")))
102118
}
103119
}
104120

105121
test("redirects"){
106122
test("max"){
107-
val res1 = requests.get("https://httpbin.org/absolute-redirect/4")
123+
val res1 = requests.get(s"http://$localHttpbin/absolute-redirect/4")
108124
assert(res1.statusCode == 200)
109-
val res2 = requests.get("https://httpbin.org/absolute-redirect/5")
125+
val res2 = requests.get(s"http://$localHttpbin/absolute-redirect/5")
110126
assert(res2.statusCode == 200)
111-
val res3 = requests.get("https://httpbin.org/absolute-redirect/6", check = false)
127+
val res3 = requests.get(s"http://$localHttpbin/absolute-redirect/6", check = false)
112128
assert(res3.statusCode == 302)
113-
val res4 = requests.get("https://httpbin.org/absolute-redirect/6", maxRedirects = 10)
129+
val res4 = requests.get(s"http://$localHttpbin/absolute-redirect/6", maxRedirects = 10)
114130
assert(res4.statusCode == 200)
115131
}
116132
test("maxRelative"){
117-
val res1 = requests.get("https://httpbin.org/relative-redirect/4")
133+
val res1 = requests.get(s"http://$localHttpbin/relative-redirect/4")
118134
assert(res1.statusCode == 200)
119-
val res2 = requests.get("https://httpbin.org/relative-redirect/5")
135+
val res2 = requests.get(s"http://$localHttpbin/relative-redirect/5")
120136
assert(res2.statusCode == 200)
121-
val res3 = requests.get("https://httpbin.org/relative-redirect/6", check = false)
137+
val res3 = requests.get(s"http://$localHttpbin/relative-redirect/6", check = false)
122138
assert(res3.statusCode == 302)
123-
val res4 = requests.get("https://httpbin.org/relative-redirect/6", maxRedirects = 10)
139+
val res4 = requests.get(s"http://$localHttpbin/relative-redirect/6", maxRedirects = 10)
124140
assert(res4.statusCode == 200)
125141
}
126142
}
127143

128144
test("test_reproduction"){
129-
requests.get("http://httpbin.org/status/304").text()
145+
requests.get(s"http://$localHttpbin/status/304").text()
130146

131147
}
132148
test("streaming"){
133-
val res1 = requests.get("http://httpbin.org/stream/5").text()
149+
val res1 = requests.get(s"http://$localHttpbin/stream/5").text()
134150
assert(res1.linesIterator.length == 5)
135-
val res2 = requests.get("http://httpbin.org/stream/52").text()
151+
val res2 = requests.get(s"http://$localHttpbin/stream/52").text()
136152
assert(res2.linesIterator.length == 52)
137153
}
138154

139155
test("timeouts"){
140156
test("read"){
141157
intercept[TimeoutException] {
142-
requests.get("https://httpbin.org/delay/1", readTimeout = 10)
158+
requests.get(s"http://$localHttpbin/delay/1", readTimeout = 10)
143159
}
144-
requests.get("https://httpbin.org/delay/1", readTimeout = 2000)
160+
requests.get(s"http://$localHttpbin/delay/1", readTimeout = 2000)
145161
intercept[TimeoutException] {
146-
requests.get("https://httpbin.org/delay/3", readTimeout = 2000)
162+
requests.get(s"http://$localHttpbin/delay/3", readTimeout = 2000)
147163
}
148164
}
149165
test("connect"){
150166
intercept[TimeoutException] {
151-
requests.get("https://httpbin.org/delay/1", connectTimeout = 1)
167+
// use remote httpbin.org so it needs more time to connect
168+
requests.get(s"https://httpbin.org/delay/1", connectTimeout = 1)
152169
}
153170
}
154171
}
@@ -167,38 +184,38 @@ object RequestTests extends TestSuite{
167184
}
168185

169186
test("decompress"){
170-
val res1 = requests.get("https://httpbin.org/gzip")
171-
assert(read(res1.text()).obj("headers").obj("Host").str == "httpbin.org")
187+
val res1 = requests.get(s"http://$localHttpbin/gzip")
188+
assert(read(res1.text()).obj("headers").obj("Host").str == localHttpbin)
172189

173-
val res2 = requests.get("https://httpbin.org/deflate")
174-
assert(read(res2).obj("headers").obj("Host").str == "httpbin.org")
190+
val res2 = requests.get(s"http://$localHttpbin/deflate")
191+
assert(read(res2).obj("headers").obj("Host").str == localHttpbin)
175192

176-
val res3 = requests.get("https://httpbin.org/gzip", autoDecompress = false)
193+
val res3 = requests.get(s"http://$localHttpbin/gzip", autoDecompress = false)
177194
assert(res3.bytes.length < res1.bytes.length)
178195

179-
val res4 = requests.get("https://httpbin.org/deflate", autoDecompress = false)
196+
val res4 = requests.get(s"http://$localHttpbin/deflate", autoDecompress = false)
180197
assert(res4.bytes.length < res2.bytes.length)
181198

182199
(res1.bytes.length, res2.bytes.length, res3.bytes.length, res4.bytes.length)
183200
}
184201

185202
test("compression"){
186203
val res1 = requests.post(
187-
"https://httpbin.org/post",
204+
s"http://$localHttpbin/post",
188205
compress = requests.Compress.None,
189206
data = new RequestBlob.ByteSourceRequestBlob("Hello World")
190207
)
191208
assert(res1.text().contains(""""Hello World""""))
192209

193210
val res2 = requests.post(
194-
"https://httpbin.org/post",
211+
s"http://$localHttpbin/post",
195212
compress = requests.Compress.Gzip,
196213
data = new RequestBlob.ByteSourceRequestBlob("I am cow")
197214
)
198215
assert(read(new String(res2.bytes))("data").toString.contains("data:application/octet-stream;base64,H4sIAAAAAA"))
199216

200217
val res3 = requests.post(
201-
"https://httpbin.org/post",
218+
s"http://$localHttpbin/post",
202219
compress = requests.Compress.Deflate,
203220
data = new RequestBlob.ByteSourceRequestBlob("Hear me moo")
204221
)
@@ -208,7 +225,7 @@ object RequestTests extends TestSuite{
208225

209226
test("headers"){
210227
test("default"){
211-
val res = requests.get("https://httpbin.org/headers").text()
228+
val res = requests.get(s"http://$localHttpbin/headers").text()
212229
val hs = read(res)("headers").obj
213230
assert(hs("User-Agent").str == "requests-scala")
214231
assert(hs("Accept-Encoding").str == "gzip, deflate")
@@ -306,7 +323,7 @@ object RequestTests extends TestSuite{
306323
// to the server. This preserves the 0.8.x behavior, and can always be overriden
307324
// by passing a comma-separated list of headers instead
308325
test("duplicateHeaders"){
309-
val res = requests.get("https://httpbin.org/get", headers = Seq("x-y" -> "a", "x-y" -> "b"))
326+
val res = requests.get(s"http://$localHttpbin/get", headers = Seq("x-y" -> "a", "x-y" -> "b"))
310327
assert(ujson.read(res)("headers")("X-Y") == Str("b")) // make sure it's not "a,b"
311328
}
312329
}

0 commit comments

Comments
 (0)