Backed out changeset 88fbb17e3c20 (bug 1865637) for causing animation related mochite...
[gecko.git] / netwerk / test / gtest / TestBufferedInputStream.cpp
blob7230fe7e5b3af2219ee336618f912d8b649daec2
1 #include "gtest/gtest.h"
3 #include "mozilla/SpinEventLoopUntil.h"
4 #include "nsBufferedStreams.h"
5 #include "nsIThread.h"
6 #include "nsNetUtil.h"
7 #include "nsStreamUtils.h"
8 #include "nsThreadUtils.h"
9 #include "Helpers.h"
11 // Helper function for creating a testing::AsyncStringStream
12 already_AddRefed<nsBufferedInputStream> CreateStream(uint32_t aSize,
13 nsCString& aBuffer) {
14 aBuffer.SetLength(aSize);
15 for (uint32_t i = 0; i < aSize; ++i) {
16 aBuffer.BeginWriting()[i] = i % 10;
19 nsCOMPtr<nsIInputStream> stream = new testing::AsyncStringStream(aBuffer);
21 RefPtr<nsBufferedInputStream> bis = new nsBufferedInputStream();
22 bis->Init(stream, aSize);
23 return bis.forget();
26 // Simple reading.
27 TEST(TestBufferedInputStream, SimpleRead)
29 const size_t kBufSize = 10;
31 nsCString buf;
32 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
34 uint64_t length;
35 ASSERT_EQ(NS_OK, bis->Available(&length));
36 ASSERT_EQ((uint64_t)kBufSize, length);
38 char buf2[kBufSize];
39 uint32_t count;
40 ASSERT_EQ(NS_OK, bis->Read(buf2, sizeof(buf2), &count));
41 ASSERT_EQ(count, buf.Length());
42 ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
45 // Simple segment reading.
46 TEST(TestBufferedInputStream, SimpleReadSegments)
48 const size_t kBufSize = 10;
50 nsCString buf;
51 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
53 char buf2[kBufSize];
54 uint32_t count;
55 ASSERT_EQ(NS_OK, bis->ReadSegments(NS_CopySegmentToBuffer, buf2, sizeof(buf2),
56 &count));
57 ASSERT_EQ(count, buf.Length());
58 ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
61 // AsyncWait - sync
62 TEST(TestBufferedInputStream, AsyncWait_sync)
64 const size_t kBufSize = 10;
66 nsCString buf;
67 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
69 RefPtr<testing::InputStreamCallback> cb = new testing::InputStreamCallback();
71 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, 0, 0, nullptr));
73 // Immediatelly called
74 ASSERT_TRUE(cb->Called());
77 // AsyncWait - async
78 TEST(TestBufferedInputStream, AsyncWait_async)
80 const size_t kBufSize = 10;
82 nsCString buf;
83 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
85 RefPtr<testing::InputStreamCallback> cb = new testing::InputStreamCallback();
86 nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
88 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, 0, 0, thread));
90 ASSERT_FALSE(cb->Called());
92 // Eventually it is called.
93 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
94 "TEST(TestBufferedInputStream, AsyncWait_async)"_ns,
95 [&]() { return cb->Called(); }));
96 ASSERT_TRUE(cb->Called());
99 // AsyncWait - sync - closureOnly
100 TEST(TestBufferedInputStream, AsyncWait_sync_closureOnly)
102 const size_t kBufSize = 10;
104 nsCString buf;
105 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
107 RefPtr<testing::InputStreamCallback> cb = new testing::InputStreamCallback();
109 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, nsIAsyncInputStream::WAIT_CLOSURE_ONLY, 0,
110 nullptr));
111 ASSERT_FALSE(cb->Called());
113 bis->CloseWithStatus(NS_ERROR_FAILURE);
115 // Immediatelly called
116 ASSERT_TRUE(cb->Called());
119 // AsyncWait - async
120 TEST(TestBufferedInputStream, AsyncWait_async_closureOnly)
122 const size_t kBufSize = 10;
124 nsCString buf;
125 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
127 RefPtr<testing::InputStreamCallback> cb = new testing::InputStreamCallback();
128 nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
130 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, nsIAsyncInputStream::WAIT_CLOSURE_ONLY, 0,
131 thread));
133 ASSERT_FALSE(cb->Called());
134 bis->CloseWithStatus(NS_ERROR_FAILURE);
135 ASSERT_FALSE(cb->Called());
137 // Eventually it is called.
138 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
139 "TEST(TestBufferedInputStream, AsyncWait_async_closureOnly)"_ns,
140 [&]() { return cb->Called(); }));
141 ASSERT_TRUE(cb->Called());
144 TEST(TestBufferedInputStream, AsyncWait_after_close)
146 const size_t kBufSize = 10;
148 nsCString buf;
149 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
151 nsCOMPtr<nsIThread> eventTarget = do_GetCurrentThread();
153 auto cb = mozilla::MakeRefPtr<testing::InputStreamCallback>();
154 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, 0, 0, eventTarget));
155 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
156 "TEST(TestBufferedInputStream, AsyncWait_after_close) 1"_ns,
157 [&]() { return cb->Called(); }));
158 ASSERT_TRUE(cb->Called());
160 ASSERT_EQ(NS_OK, bis->Close());
162 cb = mozilla::MakeRefPtr<testing::InputStreamCallback>();
163 ASSERT_EQ(NS_OK, bis->AsyncWait(cb, 0, 0, eventTarget));
164 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
165 "TEST(TestBufferedInputStream, AsyncWait_after_close) 2"_ns,
166 [&]() { return cb->Called(); }));
167 ASSERT_TRUE(cb->Called());
170 TEST(TestBufferedInputStream, AsyncLengthWait_after_close)
172 nsCString buf{"The Quick Brown Fox Jumps over the Lazy Dog"};
173 const size_t kBufSize = 44;
175 RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);
177 nsCOMPtr<nsIThread> eventTarget = do_GetCurrentThread();
179 auto cb = mozilla::MakeRefPtr<testing::LengthCallback>();
180 ASSERT_EQ(NS_OK, bis->AsyncLengthWait(cb, eventTarget));
181 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
182 "TEST(TestBufferedInputStream, AsyncLengthWait_after_close) 1"_ns,
183 [&]() { return cb->Called(); }));
184 ASSERT_TRUE(cb->Called());
186 uint64_t length;
187 ASSERT_EQ(NS_OK, bis->Available(&length));
188 ASSERT_EQ((uint64_t)kBufSize, length);
190 cb = mozilla::MakeRefPtr<testing::LengthCallback>();
191 ASSERT_EQ(NS_OK, bis->AsyncLengthWait(cb, eventTarget));
192 MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil(
193 "TEST(TestBufferedInputStream, AsyncLengthWait_after_close) 2"_ns,
194 [&]() { return cb->Called(); }));
195 ASSERT_TRUE(cb->Called());
198 // This stream returns a few bytes on the first read, and error on the second.
199 class BrokenInputStream : public nsIInputStream {
200 NS_DECL_THREADSAFE_ISUPPORTS
201 NS_DECL_NSIINPUTSTREAM
202 private:
203 virtual ~BrokenInputStream() = default;
204 bool mFirst = true;
207 NS_IMPL_ISUPPORTS(BrokenInputStream, nsIInputStream)
209 NS_IMETHODIMP BrokenInputStream::Close(void) { return NS_OK; }
211 NS_IMETHODIMP BrokenInputStream::Available(uint64_t* _retval) {
212 *_retval = 100;
213 return NS_OK;
216 NS_IMETHODIMP BrokenInputStream::StreamStatus(void) { return NS_OK; }
218 NS_IMETHODIMP BrokenInputStream::Read(char* aBuf, uint32_t aCount,
219 uint32_t* _retval) {
220 if (mFirst) {
221 aBuf[0] = 'h';
222 aBuf[1] = 'e';
223 aBuf[2] = 'l';
224 aBuf[3] = 0;
225 *_retval = 4;
226 mFirst = false;
227 return NS_OK;
229 return NS_ERROR_CORRUPTED_CONTENT;
232 NS_IMETHODIMP BrokenInputStream::ReadSegments(nsWriteSegmentFun aWriter,
233 void* aClosure, uint32_t aCount,
234 uint32_t* _retval) {
235 return NS_ERROR_NOT_IMPLEMENTED;
238 NS_IMETHODIMP BrokenInputStream::IsNonBlocking(bool* _retval) {
239 *_retval = false;
240 return NS_OK;
243 // Check that the error from BrokenInputStream::Read is propagated
244 // through NS_ReadInputStreamToString
245 TEST(TestBufferedInputStream, BrokenInputStreamToBuffer)
247 nsAutoCString out;
248 RefPtr<BrokenInputStream> stream = new BrokenInputStream();
250 nsresult rv = NS_ReadInputStreamToString(stream, out, -1);
251 ASSERT_EQ(rv, NS_ERROR_CORRUPTED_CONTENT);