зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1636823 - nsMultiplexInputStream should not be blocking and nsIAsyncInputStream at the same time - part 3 - tests, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D76998
This commit is contained in:
Родитель
699028c74a
Коммит
8c01ca65b0
|
@ -49,6 +49,7 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
rv = multiplexStream->AppendStream(inputStream3);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
int64_t tell;
|
||||
uint64_t length;
|
||||
uint32_t count;
|
||||
char readBuf[4096];
|
||||
|
@ -62,6 +63,9 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 1,
|
||||
length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 1);
|
||||
|
||||
// Check read is correct
|
||||
rv = stream->Read(readBuf, 3, &count);
|
||||
|
@ -72,6 +76,9 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 4,
|
||||
length);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "ell", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 4);
|
||||
|
||||
// Seek to start of third input stream
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET,
|
||||
|
@ -80,6 +87,9 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf3.Length(), length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length() + buf2.Length());
|
||||
|
||||
// Check read is correct
|
||||
rv = stream->Read(readBuf, 5, &count);
|
||||
|
@ -89,6 +99,9 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf3.Length() - 5, length);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "Foo b", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length() + buf2.Length() + 5);
|
||||
|
||||
// Seek back to start of second stream (covers bug 1272371)
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, buf1.Length());
|
||||
|
@ -96,6 +109,9 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf2.Length() + buf3.Length(), length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length());
|
||||
|
||||
// Check read is correct
|
||||
rv = stream->Read(readBuf, 6, &count);
|
||||
|
@ -105,6 +121,177 @@ TEST(MultiplexInputStream, Seek_SET)
|
|||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf2.Length() - 6 + buf3.Length(), length);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "The qu", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length() + 6);
|
||||
}
|
||||
|
||||
TEST(MultiplexInputStream, Seek_CUR)
|
||||
{
|
||||
nsCString buf1;
|
||||
nsCString buf2;
|
||||
nsCString buf3;
|
||||
buf1.AssignLiteral("Hello world");
|
||||
buf2.AssignLiteral("The quick brown fox jumped over the lazy dog");
|
||||
buf3.AssignLiteral("Foo bar");
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream1;
|
||||
nsCOMPtr<nsIInputStream> inputStream2;
|
||||
nsCOMPtr<nsIInputStream> inputStream3;
|
||||
nsresult rv = NS_NewCStringInputStream(getter_AddRefs(inputStream1), buf1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inputStream2), buf2);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inputStream3), buf3);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
|
||||
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
|
||||
ASSERT_TRUE(multiplexStream);
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multiplexStream));
|
||||
ASSERT_TRUE(stream);
|
||||
|
||||
rv = multiplexStream->AppendStream(inputStream1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = multiplexStream->AppendStream(inputStream2);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = multiplexStream->AppendStream(inputStream3);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
int64_t tell;
|
||||
uint64_t length;
|
||||
uint32_t count;
|
||||
char readBuf[4096];
|
||||
nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(multiplexStream);
|
||||
ASSERT_TRUE(seekStream);
|
||||
|
||||
// Seek forward in first input stream
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_CUR, 1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 1,
|
||||
length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 1);
|
||||
|
||||
// Check read is correct
|
||||
rv = stream->Read(readBuf, 3, &count);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)3, count);
|
||||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)buf1.Length() + buf2.Length() + buf3.Length() - 4,
|
||||
length);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "ell", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 4);
|
||||
|
||||
// Let's go to the second stream
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_CUR, 11);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 15);
|
||||
rv = stream->Read(readBuf, 3, &count);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)3, count);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "qui", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 18);
|
||||
|
||||
// Let's go back to the first stream
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_CUR, -9);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 9);
|
||||
rv = stream->Read(readBuf, 3, &count);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((uint64_t)3, count);
|
||||
ASSERT_EQ(0, strncmp(readBuf, "ldT", count));
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 12);
|
||||
}
|
||||
|
||||
TEST(MultiplexInputStream, Seek_END)
|
||||
{
|
||||
nsCString buf1;
|
||||
nsCString buf2;
|
||||
nsCString buf3;
|
||||
buf1.AssignLiteral("Hello world");
|
||||
buf2.AssignLiteral("The quick brown fox jumped over the lazy dog");
|
||||
buf3.AssignLiteral("Foo bar");
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream1;
|
||||
nsCOMPtr<nsIInputStream> inputStream2;
|
||||
nsCOMPtr<nsIInputStream> inputStream3;
|
||||
nsresult rv = NS_NewCStringInputStream(getter_AddRefs(inputStream1), buf1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inputStream2), buf2);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inputStream3), buf3);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
|
||||
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
|
||||
ASSERT_TRUE(multiplexStream);
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multiplexStream));
|
||||
ASSERT_TRUE(stream);
|
||||
|
||||
rv = multiplexStream->AppendStream(inputStream1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = multiplexStream->AppendStream(inputStream2);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = multiplexStream->AppendStream(inputStream3);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
int64_t tell;
|
||||
uint64_t length;
|
||||
nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(multiplexStream);
|
||||
ASSERT_TRUE(seekStream);
|
||||
|
||||
// SEEK_END wants <=0 values
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_END, 1);
|
||||
ASSERT_TRUE(NS_FAILED(rv));
|
||||
|
||||
// Let's go to the end.
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_END, 0);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ((int64_t)0, length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length() + buf2.Length() + buf3.Length());
|
||||
|
||||
// -1
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_END, -1);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(1, length);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, buf1.Length() + buf2.Length() + buf3.Length() - 1);
|
||||
|
||||
// Almost at the beginning
|
||||
tell = 1;
|
||||
tell -= buf1.Length();
|
||||
tell -= buf2.Length();
|
||||
tell -= buf3.Length();
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_END, tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
rv = stream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(length, buf1.Length() + buf2.Length() + buf3.Length() - 1);
|
||||
rv = seekStream->Tell(&tell);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(tell, 1);
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIInputStream> CreateStreamHelper() {
|
||||
|
@ -302,6 +489,42 @@ class AsyncStream final : public nsIAsyncInputStream {
|
|||
|
||||
NS_IMPL_ISUPPORTS(AsyncStream, nsIInputStream, nsIAsyncInputStream)
|
||||
|
||||
class BlockingStream final : public nsIInputStream {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
BlockingStream() = default;
|
||||
|
||||
NS_IMETHOD
|
||||
Available(uint64_t* aLength) override { return NS_BASE_STREAM_CLOSED; }
|
||||
|
||||
NS_IMETHOD
|
||||
Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override {
|
||||
MOZ_CRASH("This should not be called!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount,
|
||||
uint32_t* aResult) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Close() override { return NS_OK; }
|
||||
|
||||
NS_IMETHOD
|
||||
IsNonBlocking(bool* aNonBlocking) override {
|
||||
*aNonBlocking = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~BlockingStream() = default;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(BlockingStream, nsIInputStream)
|
||||
|
||||
TEST(TestMultiplexInputStream, Available)
|
||||
{
|
||||
nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
|
||||
|
@ -586,3 +809,56 @@ TEST(TestMultiplexInputStream, LengthInputStream)
|
|||
ASSERT_FALSE(callback1->Called());
|
||||
ASSERT_TRUE(callback2->Called());
|
||||
}
|
||||
|
||||
void BlockingVsAsyncHelper(nsIMultiplexInputStream* aStream, bool aNonBlocking,
|
||||
bool aAsyncStream) {
|
||||
MOZ_ASSERT(aStream);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(aStream);
|
||||
ASSERT_TRUE(!!stream);
|
||||
|
||||
bool nonBlocking = false;
|
||||
nsresult rv = stream->IsNonBlocking(&nonBlocking);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_TRUE(nonBlocking == aNonBlocking);
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStream> asyncStream(do_QueryInterface(aStream));
|
||||
ASSERT_TRUE(!!asyncStream == aAsyncStream);
|
||||
}
|
||||
|
||||
TEST(TestMultiplexInputStream, BlockingVsAsync)
|
||||
{
|
||||
nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
|
||||
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
|
||||
|
||||
// An empty stream is non-blocking and not-async
|
||||
BlockingVsAsyncHelper(multiplexStream, true, false);
|
||||
|
||||
// Adding a non-blocking, not-async stream, we are still non-blocking and
|
||||
// not-async.
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
nsresult rv = NS_NewCStringInputStream(getter_AddRefs(inputStream), buf);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = multiplexStream->AppendStream(inputStream);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
BlockingVsAsyncHelper(multiplexStream, true, false);
|
||||
|
||||
// Let's add a blocking stream, not-async. It will become blocking.
|
||||
RefPtr<BlockingStream> bs = new BlockingStream();
|
||||
rv = multiplexStream->AppendStream(bs);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
BlockingVsAsyncHelper(multiplexStream, false, false);
|
||||
|
||||
// Let's add an async stream. Now we are async!
|
||||
RefPtr<AsyncStream> as = new AsyncStream(10);
|
||||
rv = multiplexStream->AppendStream(as);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
BlockingVsAsyncHelper(multiplexStream, false, false);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче