1 #include "gtest/gtest.h"
3 #include "nsIStreamTransportService.h"
4 #include "nsStreamUtils.h"
5 #include "nsThreadUtils.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
);
19 nsCOMPtr
<nsIStreamTransportService
> sts
=
20 do_GetService(kStreamTransportServiceCID
, &rv
);
23 nsCOMPtr
<nsITransport
> transport
;
24 rv
= sts
->CreateInputTransport(source
, true, getter_AddRefs(transport
));
27 nsCOMPtr
<nsIInputStream
> wrapper
;
28 rv
= transport
->OpenInputStream(0, 0, 0, getter_AddRefs(wrapper
));
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
;
41 NS_DECL_THREADSAFE_ISUPPORTS
43 explicit BlockingSyncStream(const nsACString
& aBuffer
) {
44 NS_NewCStringInputStream(getter_AddRefs(mStream
), aBuffer
);
48 Available(uint64_t* aLength
) override
{ return mStream
->Available(aLength
); }
51 StreamStatus() override
{ return mStream
->StreamStatus(); }
54 Read(char* aBuffer
, uint32_t aCount
, uint32_t* aReadCount
) override
{
55 return mStream
->Read(aBuffer
, aCount
, aReadCount
);
59 ReadSegments(nsWriteSegmentFun aWriter
, void* aClosure
, uint32_t aCount
,
60 uint32_t* aResult
) override
{
61 return mStream
->ReadSegments(aWriter
, aClosure
, aCount
, aResult
);
65 Close() override
{ return mStream
->Close(); }
68 IsNonBlocking(bool* aNonBlocking
) override
{
69 *aNonBlocking
= false;
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
));
89 nsresult rv
= NS_ReadInputStreamToString(ais
, data
, -1);
92 ASSERT_TRUE(data
.EqualsLiteral("Hello world"));
95 class BlockingAsyncStream final
: public nsIAsyncInputStream
{
96 nsCOMPtr
<nsIInputStream
> mStream
;
100 NS_DECL_THREADSAFE_ISUPPORTS
102 explicit BlockingAsyncStream(const nsACString
& aBuffer
) : mPending(false) {
103 NS_NewCStringInputStream(getter_AddRefs(mStream
), aBuffer
);
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.
119 StreamStatus() override
{ return mStream
->StreamStatus(); }
122 Read(char* aBuffer
, uint32_t aCount
, uint32_t* aReadCount
) override
{
123 mPending
= !mPending
;
125 return NS_BASE_STREAM_WOULD_BLOCK
;
128 // 1 char at the time, just to test the asyncWait+Read loop a bit more.
131 return mStream
->Read(aBuffer
, aCount
, aReadCount
);
135 ReadSegments(nsWriteSegmentFun aWriter
, void* aClosure
, uint32_t aCount
,
136 uint32_t* aResult
) override
{
137 mPending
= !mPending
;
139 return NS_BASE_STREAM_WOULD_BLOCK
;
142 // 1 char at the time, just to test the asyncWait+Read loop a bit more.
145 return mStream
->ReadSegments(aWriter
, aClosure
, aCount
, aResult
);
149 Close() override
{ return mStream
->Close(); }
152 IsNonBlocking(bool* aNonBlocking
) override
{
153 *aNonBlocking
= false;
158 CloseWithStatus(nsresult aStatus
) override
{ return Close(); }
161 AsyncWait(nsIInputStreamCallback
* aCallback
, uint32_t aFlags
,
162 uint32_t aRequestedCount
, nsIEventTarget
* aEventTarget
) override
{
167 RefPtr
<BlockingAsyncStream
> self
= this;
168 nsCOMPtr
<nsIInputStreamCallback
> callback
= aCallback
;
170 nsCOMPtr
<nsIRunnable
> r
= NS_NewRunnableFunction(
172 [self
, callback
]() { callback
->OnInputStreamReady(self
); });
175 aEventTarget
->Dispatch(r
.forget());
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
));
200 nsresult rv
= NS_ReadInputStreamToString(ais
, data
, -1);
201 ASSERT_EQ(NS_OK
, rv
);
203 ASSERT_TRUE(data
.EqualsLiteral("Hello world"));