12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/native/input_stream_impl.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/android/jni_android.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/android/scoped_java_ref.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "jni/InputStreamUnittest_jni.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_byte_range.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using android_webview::InputStream;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using android_webview::InputStreamImpl;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::android::AttachCurrentThread;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::android::ScopedJavaLocalRef;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::IOBuffer;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::DoAll;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Ge;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Lt;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Ne;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::NotNull;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SetArgPointee;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Test;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class InputStreamTest : public Test {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InputStreamTest() {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    env_ = AttachCurrentThread();
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_THAT(env_, NotNull());
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(android_webview::RegisterInputStream(env_));
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(RegisterNativesImpl(env_));
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<IOBuffer> DoReadCountedStreamTest(int stream_size,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  int bytes_requested,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  int* bytes_read) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedJavaLocalRef<jobject> counting_jstream =
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Java_InputStreamUnittest_getCountingStream(env_, stream_size);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(counting_jstream.is_null());
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<InputStream> input_stream(
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new InputStreamImpl(counting_jstream));
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, bytes_read));
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return buffer;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env_;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(InputStreamTest, ReadEmptyStream) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedJavaLocalRef<jobject> empty_jstream =
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Java_InputStreamUnittest_getEmptyStream(env_);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(empty_jstream.is_null());
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<InputStream> input_stream(new InputStreamImpl(empty_jstream));
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int bytes_requested = 10;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, bytes_read);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(InputStreamTest, ReadStreamPartial) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int bytes_requested = 128;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DoReadCountedStreamTest(bytes_requested * 2, bytes_requested, &bytes_read);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(bytes_requested, bytes_read);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(InputStreamTest, ReadStreamCompletely) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int bytes_requested = 42;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(bytes_requested, bytes_read);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(InputStreamTest, TryReadMoreThanBuffer) {
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const int buffer_size = 3 * InputStreamImpl::kBufferSize;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DoReadCountedStreamTest(buffer_size, buffer_size * 2, &bytes_read);
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(buffer_size, bytes_read);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(InputStreamTest, CheckContentsReadCorrectly) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int bytes_requested = 256;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<IOBuffer> buffer =
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(bytes_requested, bytes_read);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < bytes_requested; ++i) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(i, (unsigned char)buffer->data()[i]);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(InputStreamTest, ReadLargeStreamPartial) {
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const int bytes_requested = 3 * InputStreamImpl::kBufferSize;
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int bytes_read = 0;
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DoReadCountedStreamTest(bytes_requested + 32, bytes_requested, &bytes_read);
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(bytes_requested, bytes_read);
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(InputStreamTest, ReadLargeStreamCompletely) {
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const int bytes_requested = 3 * InputStreamImpl::kBufferSize;
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int bytes_read = 0;
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DoReadCountedStreamTest(bytes_requested, bytes_requested, &bytes_read);
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(bytes_requested, bytes_read);
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(InputStreamTest, DoesNotCrashWhenExceptionThrown) {
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedJavaLocalRef<jobject> throw_jstream =
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Java_InputStreamUnittest_getThrowingStream(env_);
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(throw_jstream.is_null());
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<InputStream> input_stream(new InputStreamImpl(throw_jstream));
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int64_t bytes_skipped;
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(input_stream->Skip(10, &bytes_skipped));
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int bytes_available;
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(input_stream->BytesAvailable(&bytes_available));
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int bytes_requested = 10;
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int bytes_read = 0;
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0, bytes_read);
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This closes the stream.
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  input_stream.reset(NULL);
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
146