blob: 183620b238aede330490166354f68eb76034ba34 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include "components/embedder_support/android/util/input_stream.h"
#include <memory>
#include "base/android/jni_android.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
// Must come after all headers that specialize FromJniType() / ToJniType().
#include "components/embedder_support/android/native_j_unittests_jni_headers/InputStreamUnittest_jni.h"
using base::android::AttachCurrentThread;
using embedder_support::InputStream;
using net::IOBuffer;
using net::IOBufferWithSize;
using testing::_;
using testing::DoAll;
using testing::Ge;
using testing::InSequence;
using testing::Lt;
using testing::Ne;
using testing::NotNull;
using testing::Return;
using testing::SetArgPointee;
using testing::Test;
class InputStreamTest : public Test {
public:
InputStreamTest() = default;
protected:
void SetUp() override {
env_ = AttachCurrentThread();
ASSERT_THAT(env_, NotNull());
}
scoped_refptr<IOBuffer> DoReadCountedStreamTest(int stream_size,
int bytes_requested,
int* bytes_read) {
std::unique_ptr<InputStream> input_stream =
Java_InputStreamUnittest_getCountingStream(env_, stream_size);
EXPECT_TRUE(input_stream);
auto buffer = base::MakeRefCounted<IOBufferWithSize>(bytes_requested);
EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, bytes_read));
return buffer;
}
raw_ptr<JNIEnv> env_;
};
TEST_F(InputStreamTest, NullStreamJniConversion) {
std::unique_ptr<InputStream> input_stream =
Java_InputStreamUnittest_getNullStream(env_);
EXPECT_FALSE(input_stream);
}
TEST_F(InputStreamTest, ReadEmptyStream) {
std::unique_ptr<InputStream> input_stream =
Java_InputStreamUnittest_getEmptyStream(env_);
EXPECT_TRUE(input_stream);
const int bytes_requested = 10;
int bytes_read = 0;
auto buffer = base::MakeRefCounted<IOBufferWithSize>(bytes_requested);
EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
EXPECT_EQ(0, bytes_read);
}
TEST_F(InputStreamTest, ReadStreamPartial) {
const int bytes_requested = 128;
int bytes_read = 0;
DoReadCountedStreamTest(bytes_requested * 2, bytes_requested, &bytes_read);
EXPECT_EQ(bytes_requested, bytes_read);
}
TEST_F(InputStreamTest, ReadStreamCompletely) {
const int bytes_requested = 42;
int bytes_read = 0;
DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
EXPECT_EQ(bytes_requested, bytes_read);
}
TEST_F(InputStreamTest, TryReadMoreThanBuffer) {
const int buffer_size = 3 * InputStream::GetIntermediateBufferSize();
int bytes_read = 0;
DoReadCountedStreamTest(buffer_size, buffer_size * 2, &bytes_read);
EXPECT_EQ(buffer_size, bytes_read);
}
TEST_F(InputStreamTest, CheckContentsReadCorrectly) {
const int bytes_requested = 256;
int bytes_read = 0;
scoped_refptr<IOBuffer> buffer =
DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
EXPECT_EQ(bytes_requested, bytes_read);
for (int i = 0; i < bytes_requested; ++i) {
EXPECT_EQ(i, (unsigned char)buffer->data()[i]);
}
}
TEST_F(InputStreamTest, ReadLargeStreamPartial) {
const int bytes_requested = 3 * InputStream::GetIntermediateBufferSize();
int bytes_read = 0;
DoReadCountedStreamTest(bytes_requested + 32, bytes_requested, &bytes_read);
EXPECT_EQ(bytes_requested, bytes_read);
}
TEST_F(InputStreamTest, ReadLargeStreamCompletely) {
const int bytes_requested = 3 * InputStream::GetIntermediateBufferSize();
int bytes_read = 0;
DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
EXPECT_EQ(bytes_requested, bytes_read);
}
TEST_F(InputStreamTest, CustomInputStreamBufferSize) {
constexpr int custom_buffer_size = 1024;
EXPECT_NE(InputStream::GetIntermediateBufferSize(), custom_buffer_size);
base::test::ScopedFeatureList feature_list;
base::FieldTrialParams params;
params["BufferSize"] = base::NumberToString(custom_buffer_size);
feature_list.InitAndEnableFeatureWithParameters(
embedder_support::kEnableCustomInputStreamBufferSize, params);
EXPECT_EQ(InputStream::GetIntermediateBufferSize(), custom_buffer_size);
}
TEST_F(InputStreamTest, DoesNotCrashWhenExceptionThrown) {
std::unique_ptr<InputStream> input_stream =
Java_InputStreamUnittest_getThrowingStream(env_);
EXPECT_TRUE(input_stream);
int64_t bytes_skipped;
EXPECT_FALSE(input_stream->Skip(10, &bytes_skipped));
int bytes_available;
EXPECT_FALSE(input_stream->BytesAvailable(&bytes_available));
const int bytes_requested = 10;
int bytes_read = 0;
auto buffer = base::MakeRefCounted<IOBufferWithSize>(bytes_requested);
EXPECT_FALSE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
EXPECT_EQ(0, bytes_read);
// This closes the stream.
input_stream.reset(nullptr);
}