tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestRandomAccessStreamUtils.cpp (6573B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "chrome/common/ipc_message.h"
      8 #include "gtest/gtest.h"
      9 #include "mozilla/NotNull.h"
     10 #include "mozilla/Result.h"
     11 #include "mozilla/ResultVariant.h"
     12 #include "mozilla/ipc/RandomAccessStreamParams.h"
     13 #include "mozilla/ipc/RandomAccessStreamUtils.h"
     14 #include "mozilla/gtest/MozAssertions.h"
     15 #include "nsAppDirectoryServiceDefs.h"
     16 #include "nsCOMPtr.h"
     17 #include "nsDirectoryServiceUtils.h"
     18 #include "nsIFile.h"
     19 #include "nsIFileStreams.h"
     20 #include "nsIRandomAccessStream.h"
     21 #include "nsNetUtil.h"
     22 #include "nsStreamUtils.h"
     23 
     24 namespace mozilla::ipc {
     25 
     26 namespace {
     27 
     28 Result<nsCOMPtr<nsIRandomAccessStream>, nsresult> CreateFileStream() {
     29  nsCOMPtr<nsIFile> dir;
     30  nsresult rv =
     31      NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(dir));
     32  if (NS_FAILED(rv)) {
     33    return Err(rv);
     34  }
     35 
     36  nsCOMPtr<nsIFile> file;
     37  rv = dir->Clone(getter_AddRefs(file));
     38  if (NS_FAILED(rv)) {
     39    return Err(rv);
     40  }
     41 
     42  rv = file->Append(u"testfile"_ns);
     43  if (NS_FAILED(rv)) {
     44    return Err(rv);
     45  }
     46 
     47  rv = file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0666);
     48  if (NS_FAILED(rv)) {
     49    return Err(rv);
     50  }
     51 
     52  nsCOMPtr<nsIRandomAccessStream> stream;
     53  rv = NS_NewLocalFileRandomAccessStream(getter_AddRefs(stream), file);
     54  if (NS_FAILED(rv)) {
     55    return Err(rv);
     56  }
     57 
     58  return stream;
     59 }
     60 
     61 // Populate an array with the given number of bytes.  Data is lorem ipsum
     62 // random text, but deterministic across multiple calls.
     63 void CreateData(uint32_t aNumBytes, nsCString& aDataOut) {
     64  static const char data[] =
     65      "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec egestas "
     66      "purus eu condimentum iaculis. In accumsan leo eget odio porttitor, non "
     67      "rhoncus nulla vestibulum. Etiam lacinia consectetur nisl nec "
     68      "sollicitudin. Sed fringilla accumsan diam, pulvinar varius massa. Duis "
     69      "mollis dignissim felis, eget tempus nisi tristique ut. Fusce euismod, "
     70      "lectus non lacinia tempor, tellus diam suscipit quam, eget hendrerit "
     71      "lacus nunc fringilla ante. Sed ultrices massa vitae risus molestie, ut "
     72      "finibus quam laoreet nullam.";
     73  static const uint32_t dataLength = sizeof(data) - 1;
     74 
     75  aDataOut.SetCapacity(aNumBytes);
     76 
     77  while (aNumBytes > 0) {
     78    uint32_t amount = std::min(dataLength, aNumBytes);
     79    aDataOut.Append(data, amount);
     80    aNumBytes -= amount;
     81  }
     82 }
     83 
     84 // Synchronously consume the given input stream and validate the resulting data
     85 // against the given string of expected values.
     86 void ConsumeAndValidateStream(nsIInputStream* aStream,
     87                              const nsACString& aExpectedData) {
     88  uint64_t available = 0;
     89  nsresult rv = aStream->Available(&available);
     90  ASSERT_NS_SUCCEEDED(rv);
     91  ASSERT_EQ(available, aExpectedData.Length());
     92 
     93  nsAutoCString outputData;
     94  rv = NS_ConsumeStream(aStream, UINT32_MAX, outputData);
     95  ASSERT_NS_SUCCEEDED(rv);
     96 
     97  ASSERT_EQ(aExpectedData.Length(), outputData.Length());
     98  ASSERT_TRUE(aExpectedData.Equals(outputData));
     99 }
    100 
    101 }  // namespace
    102 
    103 TEST(RandomAccessStreamUtils, NullRandomAccessStream_MaybeSerialize)
    104 {
    105  nsCOMPtr<nsIRandomAccessStream> stream;
    106 
    107  Maybe<RandomAccessStreamParams> streamParams =
    108      SerializeRandomAccessStream(stream, nullptr);
    109 
    110  ASSERT_TRUE(streamParams.isNothing());
    111 
    112  auto res = DeserializeRandomAccessStream(streamParams);
    113  ASSERT_TRUE(res.isOk());
    114 
    115  nsCOMPtr<nsIRandomAccessStream> stream2 = res.unwrap();
    116  ASSERT_EQ(stream2, nullptr);
    117 }
    118 
    119 TEST(RandomAccessStreamUtils, FileRandomAccessStream_Serialize)
    120 {
    121  const uint32_t dataSize = 256;
    122 
    123  auto res = CreateFileStream();
    124  ASSERT_TRUE(res.isOk());
    125 
    126  auto stream = res.unwrap();
    127  ASSERT_TRUE(stream);
    128 
    129  nsCOMPtr<nsIFileRandomAccessStream> fileStream = do_QueryInterface(stream);
    130  ASSERT_TRUE(fileStream);
    131 
    132  nsCString inputData;
    133  CreateData(dataSize, inputData);
    134 
    135  uint32_t numWritten = 0;
    136  nsresult rv = stream->OutputStream()->Write(inputData.BeginReading(),
    137                                              inputData.Length(), &numWritten);
    138  ASSERT_NS_SUCCEEDED(rv);
    139  ASSERT_EQ(numWritten, dataSize);
    140 
    141  RandomAccessStreamParams streamParams = SerializeRandomAccessStream(
    142      WrapMovingNotNullUnchecked(std::move(stream)), nullptr);
    143 
    144  ASSERT_EQ(streamParams.type(),
    145            RandomAccessStreamParams::TFileRandomAccessStreamParams);
    146 
    147  auto res2 = DeserializeRandomAccessStream(streamParams);
    148  ASSERT_TRUE(res2.isOk());
    149 
    150  NotNull<nsCOMPtr<nsIRandomAccessStream>> stream2 = res2.unwrap();
    151 
    152  nsCOMPtr<nsIFileRandomAccessStream> fileStream2 =
    153      do_QueryInterface(stream2.get());
    154  ASSERT_TRUE(fileStream2);
    155 
    156  int64_t offset;
    157  rv = stream2->Tell(&offset);
    158  ASSERT_NS_SUCCEEDED(rv);
    159  ASSERT_EQ(offset, dataSize);
    160 
    161  rv = stream2->Seek(nsISeekableStream::NS_SEEK_SET, 0);
    162  ASSERT_NS_SUCCEEDED(rv);
    163 
    164  ConsumeAndValidateStream(stream2->InputStream(), inputData);
    165 }
    166 
    167 TEST(RandomAccessStreamUtils, FileRandomAccessStream_MaybeSerialize)
    168 {
    169  const uint32_t dataSize = 512;
    170 
    171  auto res = CreateFileStream();
    172  ASSERT_TRUE(res.isOk());
    173 
    174  auto stream = res.unwrap();
    175  ASSERT_TRUE(stream);
    176 
    177  nsCOMPtr<nsIFileRandomAccessStream> fileStream = do_QueryInterface(stream);
    178  ASSERT_TRUE(fileStream);
    179 
    180  nsCString inputData;
    181  CreateData(dataSize, inputData);
    182 
    183  uint32_t numWritten = 0;
    184  nsresult rv = stream->OutputStream()->Write(inputData.BeginReading(),
    185                                              inputData.Length(), &numWritten);
    186  ASSERT_NS_SUCCEEDED(rv);
    187  ASSERT_EQ(numWritten, dataSize);
    188 
    189  Maybe<RandomAccessStreamParams> streamParams =
    190      SerializeRandomAccessStream(stream, nullptr);
    191 
    192  ASSERT_TRUE(streamParams);
    193  ASSERT_EQ(streamParams->type(),
    194            RandomAccessStreamParams::TFileRandomAccessStreamParams);
    195 
    196  auto res2 = DeserializeRandomAccessStream(streamParams);
    197  ASSERT_TRUE(res2.isOk());
    198 
    199  nsCOMPtr<nsIRandomAccessStream> stream2 = res2.unwrap();
    200  ASSERT_TRUE(stream2);
    201 
    202  nsCOMPtr<nsIFileRandomAccessStream> fileStream2 = do_QueryInterface(stream2);
    203  ASSERT_TRUE(fileStream2);
    204 
    205  int64_t offset;
    206  rv = stream2->Tell(&offset);
    207  ASSERT_NS_SUCCEEDED(rv);
    208  ASSERT_EQ(offset, dataSize);
    209 
    210  rv = stream2->Seek(nsISeekableStream::NS_SEEK_SET, 0);
    211  ASSERT_NS_SUCCEEDED(rv);
    212 
    213  ConsumeAndValidateStream(stream2->InputStream(), inputData);
    214 }
    215 
    216 }  // namespace mozilla::ipc