Bug 1931425 - Limit how often moz-label's #setStyles runs r=reusable-components-revie...
[gecko.git] / netwerk / test / gtest / TestInputStreamTransport.cpp
blobde19f48147790d642e816a9e9d35dc0a851e33df
1 #include "gtest/gtest.h"
3 #include "nsIStreamTransportService.h"
4 #include "nsStreamUtils.h"
5 #include "nsThreadUtils.h"
6 #include "Helpers.h"
7 #include "nsNetCID.h"
8 #include "nsServiceManagerUtils.h"
9 #include "nsITransport.h"
10 #include "nsNetUtil.h"
12 static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
14 void CreateStream(already_AddRefed<nsIInputStream> aSource,
15 nsIAsyncInputStream** aStream) {
16 nsCOMPtr<nsIInputStream> source = std::move(aSource);
18 nsresult rv;
19 nsCOMPtr<nsIStreamTransportService> sts =
20 do_GetService(kStreamTransportServiceCID, &rv);
21 ASSERT_EQ(NS_OK, rv);
23 nsCOMPtr<nsITransport> transport;
24 rv = sts->CreateInputTransport(source, true, getter_AddRefs(transport));
25 ASSERT_EQ(NS_OK, rv);
27 nsCOMPtr<nsIInputStream> wrapper;
28 rv = transport->OpenInputStream(0, 0, 0, getter_AddRefs(wrapper));
29 ASSERT_EQ(NS_OK, rv);
31 nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(wrapper);
32 MOZ_RELEASE_ASSERT(asyncStream);
34 asyncStream.forget(aStream);
37 class BlockingSyncStream final : public nsIInputStream {
38 nsCOMPtr<nsIInputStream> mStream;
40 public:
41 NS_DECL_THREADSAFE_ISUPPORTS
43 explicit BlockingSyncStream(const nsACString& aBuffer) {
44 NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
47 NS_IMETHOD
48 Available(uint64_t* aLength) override { return mStream->Available(aLength); }
50 NS_IMETHOD
51 StreamStatus() override { return mStream->StreamStatus(); }
53 NS_IMETHOD
54 Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override {
55 return mStream->Read(aBuffer, aCount, aReadCount);
58 NS_IMETHOD
59 ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount,
60 uint32_t* aResult) override {
61 return mStream->ReadSegments(aWriter, aClosure, aCount, aResult);
64 NS_IMETHOD
65 Close() override { return mStream->Close(); }
67 NS_IMETHOD
68 IsNonBlocking(bool* aNonBlocking) override {
69 *aNonBlocking = false;
70 return NS_OK;
73 private:
74 ~BlockingSyncStream() = default;
77 NS_IMPL_ISUPPORTS(BlockingSyncStream, nsIInputStream)
79 // Testing a simple blocking stream.
80 TEST(TestInputStreamTransport, BlockingNotAsync)
82 RefPtr<BlockingSyncStream> stream = new BlockingSyncStream("Hello world"_ns);
84 nsCOMPtr<nsIAsyncInputStream> ais;
85 CreateStream(stream.forget(), getter_AddRefs(ais));
86 ASSERT_TRUE(!!ais);
88 nsAutoCString data;
89 nsresult rv = NS_ReadInputStreamToString(ais, data, -1);
90 ASSERT_EQ(NS_OK, rv);
92 ASSERT_TRUE(data.EqualsLiteral("Hello world"));
95 class BlockingAsyncStream final : public nsIAsyncInputStream {
96 nsCOMPtr<nsIInputStream> mStream;
97 bool mPending;
99 public:
100 NS_DECL_THREADSAFE_ISUPPORTS
102 explicit BlockingAsyncStream(const nsACString& aBuffer) : mPending(false) {
103 NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
106 NS_IMETHOD
107 Available(uint64_t* aLength) override {
108 mStream->Available(aLength);
110 // 1 char at the time, just to test the asyncWait+Read loop a bit more.
111 if (*aLength > 0) {
112 *aLength = 1;
115 return NS_OK;
118 NS_IMETHOD
119 StreamStatus() override { return mStream->StreamStatus(); }
121 NS_IMETHOD
122 Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override {
123 mPending = !mPending;
124 if (mPending) {
125 return NS_BASE_STREAM_WOULD_BLOCK;
128 // 1 char at the time, just to test the asyncWait+Read loop a bit more.
129 aCount = 1;
131 return mStream->Read(aBuffer, aCount, aReadCount);
134 NS_IMETHOD
135 ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount,
136 uint32_t* aResult) override {
137 mPending = !mPending;
138 if (mPending) {
139 return NS_BASE_STREAM_WOULD_BLOCK;
142 // 1 char at the time, just to test the asyncWait+Read loop a bit more.
143 aCount = 1;
145 return mStream->ReadSegments(aWriter, aClosure, aCount, aResult);
148 NS_IMETHOD
149 Close() override { return mStream->Close(); }
151 NS_IMETHOD
152 IsNonBlocking(bool* aNonBlocking) override {
153 *aNonBlocking = false;
154 return NS_OK;
157 NS_IMETHOD
158 CloseWithStatus(nsresult aStatus) override { return Close(); }
160 NS_IMETHOD
161 AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
162 uint32_t aRequestedCount, nsIEventTarget* aEventTarget) override {
163 if (!aCallback) {
164 return NS_OK;
167 RefPtr<BlockingAsyncStream> self = this;
168 nsCOMPtr<nsIInputStreamCallback> callback = aCallback;
170 nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
171 "gtest-asyncwait",
172 [self, callback]() { callback->OnInputStreamReady(self); });
174 if (aEventTarget) {
175 aEventTarget->Dispatch(r.forget());
176 } else {
177 r->Run();
180 return NS_OK;
183 private:
184 ~BlockingAsyncStream() = default;
187 NS_IMPL_ISUPPORTS(BlockingAsyncStream, nsIInputStream, nsIAsyncInputStream)
189 // Testing an async blocking stream.
190 TEST(TestInputStreamTransport, BlockingAsync)
192 RefPtr<BlockingAsyncStream> stream =
193 new BlockingAsyncStream("Hello world"_ns);
195 nsCOMPtr<nsIAsyncInputStream> ais;
196 CreateStream(stream.forget(), getter_AddRefs(ais));
197 ASSERT_TRUE(!!ais);
199 nsAutoCString data;
200 nsresult rv = NS_ReadInputStreamToString(ais, data, -1);
201 ASSERT_EQ(NS_OK, rv);
203 ASSERT_TRUE(data.EqualsLiteral("Hello world"));