1cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom/* 2cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * Copyright (C) 2013 The Android Open Source Project 3cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * 4cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * you may not use this file except in compliance with the License. 6cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * You may obtain a copy of the License at 7cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * 8cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * 10cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 11cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * See the License for the specific language governing permissions and 14cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom * limitations under the License. 15cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom */ 16cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 17cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom#include "file_output_stream.h" 18cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom#include "vector_output_stream.h" 19cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 20e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h" 21a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "base/logging.h" 2210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko#include "base/stl_util.h" 23a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "buffered_output_stream.h" 24a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_runtime_test.h" 25a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 26cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromnamespace art { 27cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass OutputStreamTest : public CommonRuntimeTest { 29cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom protected: 30cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom void CheckOffset(off_t expected) { 3149a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t actual = output_stream_->Seek(0, kSeekCurrent); 328d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(expected, actual); 33cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom } 34cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 35cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom void SetOutputStream(OutputStream& output_stream) { 36cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom output_stream_ = &output_stream; 37cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom } 38cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 39cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom void GenerateTestOutput() { 408d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(3, output_stream_->Seek(3, kSeekCurrent)); 41cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckOffset(3); 428d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(2, output_stream_->Seek(2, kSeekSet)); 43cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckOffset(2); 44cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom uint8_t buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 458d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_TRUE(output_stream_->WriteFully(buf, 2)); 46cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckOffset(4); 478d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(6, output_stream_->Seek(2, kSeekEnd)); 48cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckOffset(6); 498d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_TRUE(output_stream_->WriteFully(buf, 4)); 50cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckOffset(10); 5198088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu EXPECT_TRUE(output_stream_->WriteFully(buf, 6)); 5210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko EXPECT_TRUE(output_stream_->Flush()); 53cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom } 54cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 55cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom void CheckTestOutput(const std::vector<uint8_t>& actual) { 56cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom uint8_t expected[] = { 5798088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu 0, 0, 1, 2, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6 58cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom }; 598d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(sizeof(expected), actual.size()); 608d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_EQ(0, memcmp(expected, &actual[0], actual.size())); 61cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom } 62cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 63cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom OutputStream* output_stream_; 64cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom}; 65cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 66cd60ac736bc7104785dc67671660d70fb434466fBrian CarlstromTEST_F(OutputStreamTest, File) { 67cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ScratchFile tmp; 68cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom FileOutputStream output_stream(tmp.GetFile()); 69cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom SetOutputStream(output_stream); 70cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom GenerateTestOutput(); 71700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> in(OS::OpenFileForReading(tmp.GetFilename().c_str())); 722cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(in.get() != nullptr); 73cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom std::vector<uint8_t> actual(in->GetLength()); 74cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom bool readSuccess = in->ReadFully(&actual[0], actual.size()); 758d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers EXPECT_TRUE(readSuccess); 76cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckTestOutput(actual); 77cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom} 78cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 79c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian CarlstromTEST_F(OutputStreamTest, Buffered) { 80c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom ScratchFile tmp; 8198088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu { 8210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko BufferedOutputStream buffered_output_stream(MakeUnique<FileOutputStream>(tmp.GetFile())); 8398088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu SetOutputStream(buffered_output_stream); 8498088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu GenerateTestOutput(); 8598088c424efd45ea3c172d4bc16e191f26a007ccZheng Xu } 86700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> in(OS::OpenFileForReading(tmp.GetFilename().c_str())); 872cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(in.get() != nullptr); 88c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom std::vector<uint8_t> actual(in->GetLength()); 89c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom bool readSuccess = in->ReadFully(&actual[0], actual.size()); 90c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom EXPECT_TRUE(readSuccess); 91c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom CheckTestOutput(actual); 92c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom} 93c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom 94cd60ac736bc7104785dc67671660d70fb434466fBrian CarlstromTEST_F(OutputStreamTest, Vector) { 95cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom std::vector<uint8_t> output; 960279ebb3efd653e6bb255470c99d26949c7bcd95Ian Rogers VectorOutputStream output_stream("test vector output", &output); 97cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom SetOutputStream(output_stream); 98cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom GenerateTestOutput(); 99cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom CheckTestOutput(output); 100cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom} 101cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom 10210c13565474de2786aad7c2e79757ea250747a15Vladimir MarkoTEST_F(OutputStreamTest, BufferedFlush) { 10310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko struct CheckingOutputStream : OutputStream { 10410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko CheckingOutputStream() 10510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko : OutputStream("dummy"), 10610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko flush_called(false) { } 10710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ~CheckingOutputStream() OVERRIDE {} 10810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 10910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko bool WriteFully(const void* buffer ATTRIBUTE_UNUSED, 11010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko size_t byte_count ATTRIBUTE_UNUSED) OVERRIDE { 11110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko LOG(FATAL) << "UNREACHABLE"; 11210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko UNREACHABLE(); 11310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko } 11410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 11510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko off_t Seek(off_t offset ATTRIBUTE_UNUSED, Whence whence ATTRIBUTE_UNUSED) OVERRIDE { 11610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko LOG(FATAL) << "UNREACHABLE"; 11710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko UNREACHABLE(); 11810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko } 11910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 12010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko bool Flush() OVERRIDE { 12110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko flush_called = true; 12210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko return true; 12310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko } 12410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 12510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko bool flush_called; 12610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko }; 12710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 12810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko std::unique_ptr<CheckingOutputStream> cos = MakeUnique<CheckingOutputStream>(); 12910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko CheckingOutputStream* checking_output_stream = cos.get(); 13010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko BufferedOutputStream buffered(std::move(cos)); 13110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ASSERT_FALSE(checking_output_stream->flush_called); 13210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko bool flush_result = buffered.Flush(); 13310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ASSERT_TRUE(flush_result); 13410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ASSERT_TRUE(checking_output_stream->flush_called); 13510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 13610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 13702e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier} // namespace art 138