Bug 1355369 - gtests for SlicedInputStream and ASyncWait, r=me

This commit is contained in:
Andrea Marchesini 2017-04-12 13:49:08 +02:00
Родитель 8b8935bd3b
Коммит 7998eae548
1 изменённых файлов: 122 добавлений и 2 удалений

Просмотреть файл

@ -6,13 +6,42 @@
#include "nsString.h"
#include "nsStringStream.h"
#include "SlicedInputStream.h"
#include "Helpers.h"
// This helper class is used to call OnInputStreamReady with the right stream
// as argument.
class InputStreamCallback final : public nsIInputStreamCallback
{
nsCOMPtr<nsIAsyncInputStream> mStream;
nsCOMPtr<nsIInputStreamCallback> mCallback;
public:
NS_DECL_THREADSAFE_ISUPPORTS
InputStreamCallback(nsIAsyncInputStream* aStream,
nsIInputStreamCallback* aCallback)
: mStream(aStream)
, mCallback(aCallback)
{}
NS_IMETHOD
OnInputStreamReady(nsIAsyncInputStream* aStream) override
{
return mCallback->OnInputStreamReady(mStream);
}
private:
~InputStreamCallback() {}
};
NS_IMPL_ISUPPORTS(InputStreamCallback, nsIInputStreamCallback)
/* We want to ensure that sliced streams work with both seekable and
* non-seekable input streams. As our string streams are seekable, we need to
* provide a string stream that doesn't permit seeking, so we can test the
* logic that emulates seeking in sliced input streams.
*/
class NonSeekableStringStream final : public nsIInputStream
class NonSeekableStringStream final : public nsIAsyncInputStream
{
nsCOMPtr<nsIInputStream> mStream;
@ -24,6 +53,11 @@ public:
NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
}
explicit NonSeekableStringStream(nsIInputStream* aStream)
: mStream(aStream)
{
}
NS_IMETHOD
Available(uint64_t* aLength) override
{
@ -55,11 +89,40 @@ public:
return mStream->IsNonBlocking(aNonBlocking);
}
NS_IMETHOD
CloseWithStatus(nsresult aStatus) override
{
nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(mStream);
if (!async) {
MOZ_CRASH("This should not happen.");
return NS_ERROR_FAILURE;
}
return async->CloseWithStatus(aStatus);
}
NS_IMETHOD
AsyncWait(nsIInputStreamCallback* aCallback,
uint32_t aFlags, uint32_t aRequestedCount,
nsIEventTarget* aEventTarget) override
{
nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(mStream);
if (!async) {
MOZ_CRASH("This should not happen.");
return NS_ERROR_FAILURE;
}
RefPtr<InputStreamCallback> callback =
new InputStreamCallback(this, aCallback);
return async->AsyncWait(callback, aFlags, aRequestedCount, aEventTarget);
}
private:
~NonSeekableStringStream() {}
};
NS_IMPL_ISUPPORTS(NonSeekableStringStream, nsIInputStream)
NS_IMPL_ISUPPORTS(NonSeekableStringStream, nsIInputStream, nsIAsyncInputStream)
// Helper function for creating a seekable nsIInputStream + a SlicedInputStream.
SlicedInputStream*
@ -373,3 +436,60 @@ TEST(TestSlicedInputStream, Seek_END_Lower) {
ASSERT_EQ((uint64_t)3, count);
ASSERT_EQ(0, strncmp(buf2, " wo", count));
}
// Check the nsIAsyncInputStream interface
TEST(TestSlicedInputStream, NoAsyncInputStream) {
const size_t kBufSize = 4096;
nsCString buf;
nsCOMPtr<nsIInputStream> sis =
CreateSeekableStreams(kBufSize, 0, kBufSize, buf);
// If the stream is not asyncInputStream, also SIS is not.
nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(sis);
ASSERT_TRUE(!async);
}
TEST(TestSlicedInputStream, AsyncInputStream) {
nsCOMPtr<nsIAsyncInputStream> reader;
nsCOMPtr<nsIAsyncOutputStream> writer;
const uint32_t segmentSize = 1024;
const uint32_t numSegments = 1;
nsresult rv = NS_NewPipe2(getter_AddRefs(reader), getter_AddRefs(writer),
true, true, // non-blocking - reader, writer
segmentSize, numSegments);
ASSERT_TRUE(NS_SUCCEEDED(rv));
nsTArray<char> inputData;
testing::CreateData(segmentSize, inputData);
// We have to wrap the reader because it implements only a partial
// nsISeekableStream interface. When ::Seek() is called, it does a MOZ_CRASH.
RefPtr<NonSeekableStringStream> wrapper =
new NonSeekableStringStream(reader);
nsCOMPtr<nsIInputStream> sis = new SlicedInputStream(wrapper, 500, 500);
nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(sis);
ASSERT_TRUE(!!async);
RefPtr<testing::InputStreamCallback> cb =
new testing::InputStreamCallback();
rv = async->AsyncWait(cb, 0, 0, nullptr);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_FALSE(cb->Called());
uint32_t numWritten = 0;
rv = writer->Write(inputData.Elements(), inputData.Length(), &numWritten);
ASSERT_TRUE(NS_SUCCEEDED(rv));
ASSERT_TRUE(cb->Called());
inputData.RemoveElementsAt(0, 500);
inputData.RemoveElementsAt(500, 24);
testing::ConsumeAndValidateStream(async, inputData);
}