tor-browser

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

TestDataStructures.cpp (22482B)


      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 /*
      8 * Test many combinations of data structures (both in argument and return
      9 * position) to ensure they are transmitted correctly.
     10 */
     11 
     12 #include "gtest/gtest.h"
     13 
     14 #include "mozilla/_ipdltest/IPDLUnitTest.h"
     15 #include "mozilla/_ipdltest/PTestDataStructuresChild.h"
     16 #include "mozilla/_ipdltest/PTestDataStructuresParent.h"
     17 #include "mozilla/_ipdltest/PTestDataStructuresSubChild.h"
     18 #include "mozilla/_ipdltest/PTestDataStructuresSubParent.h"
     19 
     20 using namespace mozilla::ipc;
     21 
     22 using RegionArray = nsTArray<nsIntRegion>;
     23 
     24 namespace mozilla::_ipdltest {
     25 
     26 static const uint32_t nactors = 10;
     27 
     28 class TestDataStructuresSubParent : public PTestDataStructuresSubParent {
     29  NS_INLINE_DECL_REFCOUNTING(TestDataStructuresSubParent, override)
     30 
     31 public:
     32  explicit TestDataStructuresSubParent(uint32_t i) : mI(i) {}
     33  uint32_t mI;
     34 
     35 private:
     36  ~TestDataStructuresSubParent() = default;
     37 };
     38 
     39 class TestDataStructuresSubChild : public PTestDataStructuresSubChild {
     40  NS_INLINE_DECL_REFCOUNTING(TestDataStructuresSubChild, override)
     41 
     42 public:
     43  explicit TestDataStructuresSubChild(uint32_t i) : mI(i) {}
     44  uint32_t mI;
     45 
     46 private:
     47  ~TestDataStructuresSubChild() = default;
     48 };
     49 
     50 inline static TestDataStructuresSubParent& Cast(
     51    PTestDataStructuresSubParent* a) {
     52  return *static_cast<TestDataStructuresSubParent*>(a);
     53 }
     54 
     55 class TestDataStructuresParent : public PTestDataStructuresParent {
     56  NS_INLINE_DECL_REFCOUNTING(TestDataStructuresParent, override)
     57 
     58 public:
     59  nsTArray<NotNull<
     60      SideVariant<PTestDataStructuresSubParent*, PTestDataStructuresSubChild*>>>
     61      kids;
     62 
     63 private:
     64  IPCResult RecvTestArrayOfInt(nsTArray<int>&& ia,
     65                               nsTArray<int>* oa) final override {
     66    EXPECT_EQ(5u, ia.Length());
     67    for (int i = 0; i < 5; ++i) EXPECT_EQ(i, ia[i]);
     68 
     69    *oa = std::move(ia);
     70 
     71    return IPC_OK();
     72  }
     73 
     74  IPCResult RecvTestArrayOfActor(
     75      nsTArray<NotNull<PTestDataStructuresSubParent*>>&& i1,
     76      nsTArray<NotNull<PTestDataStructuresSubParent*>>* o1) final override {
     77    EXPECT_EQ(nactors, i1.Length());
     78    for (uint32_t i = 0; i < i1.Length(); ++i) EXPECT_EQ(i, Cast(i1[i]).mI);
     79    *o1 = std::move(i1);
     80    return IPC_OK();
     81  }
     82 
     83  IPCResult RecvTestUnion(const IntDouble& i1, const IntDouble& i2,
     84                          IntDouble* o1, IntDouble* o2) final override {
     85    EXPECT_EQ(42, i1.get_int());
     86    EXPECT_EQ(4.0, i2.get_double());
     87 
     88    *o1 = i1;
     89    *o2 = i2;
     90 
     91    return IPC_OK();
     92  }
     93 
     94  IPCResult RecvTestArrayOfUnion(nsTArray<IntDouble>&& i1,
     95                                 nsTArray<IntDouble>* o1) final override {
     96    EXPECT_EQ(4u, i1.Length());
     97    EXPECT_EQ(1, i1[0].get_int());
     98    EXPECT_EQ(2.0, i1[1].get_double());
     99    EXPECT_EQ(3, i1[2].get_int());
    100    EXPECT_EQ(4.0, i1[3].get_double());
    101 
    102    *o1 = std::move(i1);
    103 
    104    return IPC_OK();
    105  }
    106 
    107  IPCResult RecvTestUnionWithArray(const IntDoubleArrays& i1,
    108                                   const IntDoubleArrays& i2,
    109                                   const IntDoubleArrays& i3,
    110                                   IntDoubleArrays* o1, IntDoubleArrays* o2,
    111                                   IntDoubleArrays* o3) final override {
    112    EXPECT_EQ(42, i1.get_int());
    113 
    114    const nsTArray<int>& i2a = i2.get_ArrayOfint();
    115    EXPECT_EQ(3u, i2a.Length());
    116    EXPECT_EQ(1, i2a[0]);
    117    EXPECT_EQ(2, i2a[1]);
    118    EXPECT_EQ(3, i2a[2]);
    119 
    120    const nsTArray<double>& i3a = i3.get_ArrayOfdouble();
    121    EXPECT_EQ(3u, i3a.Length());
    122    EXPECT_EQ(1.0, i3a[0]);
    123    EXPECT_EQ(2.0, i3a[1]);
    124    EXPECT_EQ(3.0, i3a[2]);
    125 
    126    *o1 = i1;
    127    *o2 = i2a;
    128    *o3 = i3a;
    129 
    130    return IPC_OK();
    131  }
    132 
    133  IPCResult RecvTestArrayOfUnionWithArray(
    134      nsTArray<IntDoubleArrays>&& i1,
    135      nsTArray<IntDoubleArrays>* o1) final override {
    136    EXPECT_EQ(3u, i1.Length());
    137 
    138    IntDoubleArrays id1(i1[0]);
    139    EXPECT_EQ(42, id1.get_int());
    140 
    141    nsTArray<int> i2a = i1[1].get_ArrayOfint().Clone();
    142    EXPECT_EQ(3u, i2a.Length());
    143    EXPECT_EQ(1, i2a[0]);
    144    EXPECT_EQ(2, i2a[1]);
    145    EXPECT_EQ(3, i2a[2]);
    146 
    147    nsTArray<double> i3a = i1[2].get_ArrayOfdouble().Clone();
    148    EXPECT_EQ(3u, i3a.Length());
    149    EXPECT_EQ(1.0, i3a[0]);
    150    EXPECT_EQ(2.0, i3a[1]);
    151    EXPECT_EQ(3.0, i3a[2]);
    152 
    153    o1->AppendElement(id1);
    154    o1->AppendElement(IntDoubleArrays(i2a));
    155    o1->AppendElement(IntDoubleArrays(i3a));
    156 
    157    return IPC_OK();
    158  }
    159 
    160  IPCResult RecvTestStructWithActor(const ActorWrapper& i1,
    161                                    ActorWrapper* o1) final override {
    162    EXPECT_FALSE(i1.actor().IsChild()) << "child side should be empty";
    163 
    164    EXPECT_EQ(i1.actor(), kids[0])
    165        << "should have got back same actor on parent side";
    166 
    167    o1->actor() = kids[0];
    168    return IPC_OK();
    169  }
    170 
    171  IPCResult RecvTestUnionWithActors(const Actors& i1, const Actors& i2,
    172                                    const Actors& i3, Actors* o1, Actors* o2,
    173                                    Actors* o3) final override {
    174    EXPECT_EQ(42, i1.get_int());
    175 
    176    nsTArray<int> i2a = i2.get_ArrayOfint().Clone();
    177    EXPECT_EQ(3u, i2a.Length());
    178    EXPECT_EQ(1, i2a[0]);
    179    EXPECT_EQ(2, i2a[1]);
    180    EXPECT_EQ(3, i2a[2]);
    181 
    182    const auto& a = i3.get_ArrayOfPTestDataStructuresSub();
    183    EXPECT_EQ(a.Length(), kids.Length());
    184    for (size_t i = 0; i < a.Length(); ++i) {
    185      EXPECT_EQ(a[i], kids[i]);
    186    }
    187 
    188    *o1 = 42;
    189    *o2 = i2a;
    190    *o3 = kids.Clone();
    191 
    192    return IPC_OK();
    193  }
    194 
    195  IPCResult RecvTestArrayOfUnionWithActors(
    196      nsTArray<Actors>&& i1, nsTArray<Actors>* o1) final override {
    197    EXPECT_EQ(3u, i1.Length());
    198    EXPECT_EQ(42, i1[0].get_int());
    199 
    200    const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
    201    EXPECT_EQ(3u, i2a.Length());
    202    EXPECT_EQ(1, i2a[0]);
    203    EXPECT_EQ(2, i2a[1]);
    204    EXPECT_EQ(3, i2a[2]);
    205 
    206    EXPECT_EQ(kids, i1[2].get_ArrayOfPTestDataStructuresSub());
    207 
    208    *o1 = std::move(i1);
    209 
    210    return IPC_OK();
    211  }
    212 
    213  IPCResult RecvTestUnions(const Unions& i1, const Unions& i2, const Unions& i3,
    214                           const Unions& i4, Unions* o1, Unions* o2, Unions* o3,
    215                           Unions* o4) final override {
    216    EXPECT_EQ(42, i1.get_int());
    217 
    218    const nsTArray<int>& i2a = i2.get_ArrayOfint();
    219    EXPECT_EQ(3u, i2a.Length());
    220    EXPECT_EQ(1, i2a[0]);
    221    EXPECT_EQ(2, i2a[1]);
    222    EXPECT_EQ(3, i2a[2]);
    223 
    224    EXPECT_EQ(kids, i3.get_ArrayOfPTestDataStructuresSub());
    225 
    226    const auto& i4a =
    227        i4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub();
    228    EXPECT_EQ(kids, i4a);
    229 
    230    *o1 = i1;
    231    *o2 = i2;
    232    *o3 = i3;
    233    *o4 = i4;
    234 
    235    return IPC_OK();
    236  }
    237 
    238  IPCResult RecvTestArrayOfUnions(nsTArray<Unions>&& i1,
    239                                  nsTArray<Unions>* o1) final override {
    240    EXPECT_EQ(42, i1[0].get_int());
    241 
    242    const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
    243    EXPECT_EQ(3u, i2a.Length());
    244    EXPECT_EQ(1, i2a[0]);
    245    EXPECT_EQ(2, i2a[1]);
    246    EXPECT_EQ(3, i2a[2]);
    247 
    248    EXPECT_EQ(kids, i1[2].get_ArrayOfPTestDataStructuresSub());
    249 
    250    const auto& i4a =
    251        i1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub();
    252    EXPECT_EQ(kids, i4a);
    253 
    254    *o1 = std::move(i1);
    255 
    256    return IPC_OK();
    257  }
    258 
    259  IPCResult RecvTestStruct(const SIntDouble& i, SIntDouble* o) final override {
    260    EXPECT_EQ(1, i.i());
    261    EXPECT_EQ(2.0, i.d());
    262    *o = i;
    263    return IPC_OK();
    264  }
    265 
    266  IPCResult RecvTestStructWithArrays(const SIntDoubleArrays& i,
    267                                     SIntDoubleArrays* o) final override {
    268    nsTArray<int> ai;
    269    ai.AppendElement(1);
    270    ai.AppendElement(2);
    271    ai.AppendElement(3);
    272 
    273    nsTArray<double> ad;
    274    ad.AppendElement(.5);
    275    ad.AppendElement(1.0);
    276    ad.AppendElement(2.0);
    277 
    278    EXPECT_EQ(42, i.i());
    279    EXPECT_EQ(ai, i.ai());
    280    EXPECT_EQ(ad, i.ad());
    281 
    282    *o = i;
    283 
    284    return IPC_OK();
    285  }
    286 
    287  IPCResult RecvTestStructWithActors(const SActors& i,
    288                                     SActors* o) final override {
    289    nsTArray<int> ai;
    290    ai.AppendElement(1);
    291    ai.AppendElement(2);
    292    ai.AppendElement(3);
    293 
    294    EXPECT_EQ(42, i.i());
    295    EXPECT_EQ(ai, i.ai());
    296    EXPECT_EQ(kids, i.ap());
    297 
    298    *o = i;
    299 
    300    return IPC_OK();
    301  }
    302 
    303  IPCResult RecvTestStructs(const Structs& i, Structs* o) final override {
    304    nsTArray<int> ai;
    305    ai.AppendElement(1);
    306    ai.AppendElement(2);
    307    ai.AppendElement(3);
    308 
    309    EXPECT_EQ(42, i.i());
    310    EXPECT_EQ(ai, i.ai());
    311    EXPECT_EQ(kids, i.ap());
    312 
    313    const SActors& ia = i.aa()[0];
    314    EXPECT_EQ(42, ia.i());
    315    EXPECT_EQ(ai, ia.ai());
    316    EXPECT_EQ(kids, ia.ap());
    317 
    318    *o = i;
    319 
    320    return IPC_OK();
    321  }
    322 
    323  IPCResult RecvTestUnionWithStructs(
    324      const WithStructs& i1, const WithStructs& i2, const WithStructs& i3,
    325      const WithStructs& i4, const WithStructs& i5, WithStructs* o1,
    326      WithStructs* o2, WithStructs* o3, WithStructs* o4,
    327      WithStructs* o5) final override {
    328    nsTArray<int> ai;
    329    ai.AppendElement(1);
    330    ai.AppendElement(2);
    331    ai.AppendElement(3);
    332 
    333    EXPECT_EQ(i1, int(42));
    334    EXPECT_EQ(i2.get_ArrayOfint(), ai);
    335    EXPECT_EQ(i3.get_ArrayOfPTestDataStructuresSub(), kids);
    336 
    337    const SActors& ia = i4.get_ArrayOfSActors()[0];
    338    EXPECT_EQ(42, ia.i());
    339    EXPECT_EQ(ai, ia.ai());
    340    EXPECT_EQ(kids, ia.ap());
    341 
    342    const Structs& is = i5.get_ArrayOfStructs()[0];
    343    EXPECT_EQ(42, is.i());
    344    EXPECT_EQ(ai, is.ai());
    345    EXPECT_EQ(kids, is.ap());
    346 
    347    const SActors& isa = is.aa()[0];
    348    EXPECT_EQ(42, isa.i());
    349    EXPECT_EQ(ai, isa.ai());
    350    EXPECT_EQ(kids, isa.ap());
    351 
    352    *o1 = i1;
    353    *o2 = i2;
    354    *o3 = i3;
    355    *o4 = i4;
    356    *o5 = i5;
    357 
    358    return IPC_OK();
    359  }
    360 
    361  IPCResult RecvTestStructWithUnions(const WithUnions& i,
    362                                     WithUnions* o) final override {
    363    EXPECT_EQ(i.i(), 42);
    364 
    365    nsTArray<int> ai;
    366    ai.AppendElement(1);
    367    ai.AppendElement(2);
    368    ai.AppendElement(3);
    369    EXPECT_EQ(ai, i.ai());
    370 
    371    EXPECT_EQ(i.ap(), kids);
    372 
    373    EXPECT_EQ(kids, i.aa()[0].get_ArrayOfPTestDataStructuresSub());
    374 
    375    const nsTArray<Unions>& iau = i.au();
    376    EXPECT_EQ(iau[0], 42);
    377    EXPECT_EQ(ai, iau[1].get_ArrayOfint());
    378    EXPECT_EQ(kids, iau[2].get_ArrayOfPTestDataStructuresSub());
    379    EXPECT_EQ(
    380        kids,
    381        iau[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
    382 
    383    *o = i;
    384 
    385    return IPC_OK();
    386  }
    387 
    388  IPCResult RecvTestUnionWithCxx(nsTArray<Op>&& sa) final override {
    389    EXPECT_EQ(sa.Length(), (size_t)1);
    390    EXPECT_EQ(Op::TSetAttrs, sa[0].type());
    391    return IPC_OK();
    392  }
    393 
    394  IPCResult RecvTestNsIntRegion(RegionArray&& ra) final override {
    395    for (RegionArray::index_type i = 0; i < ra.Length(); ++i) {
    396      // if |ra| has been realloc()d and given a different allocator
    397      // chunk, this loop will nondeterministically crash or iloop.
    398      for (auto iter = ra[i].RectIter(); !iter.Done(); iter.Next()) {
    399        (void)iter.Get();
    400      }
    401    }
    402    return IPC_OK();
    403  }
    404 
    405  ~TestDataStructuresParent() = default;
    406 };
    407 
    408 class TestDataStructuresChild : public PTestDataStructuresChild {
    409  NS_INLINE_DECL_REFCOUNTING(TestDataStructuresChild, override)
    410 
    411 private:
    412  nsTArray<NotNull<
    413      SideVariant<PTestDataStructuresSubParent*, PTestDataStructuresSubChild*>>>
    414      kids;
    415  nsTArray<NotNull<PTestDataStructuresSubChild*>> kidsDirect;
    416 
    417  already_AddRefed<PTestDataStructuresSubChild>
    418  AllocPTestDataStructuresSubChild(const int& i) final override {
    419    auto child = MakeRefPtr<TestDataStructuresSubChild>(i);
    420    kids.AppendElement(WrapNotNull(child));
    421    kidsDirect.AppendElement(WrapNotNull(child));
    422    return child.forget();
    423  }
    424 
    425  IPCResult RecvStart() final override {
    426    TestArrayOfInt();
    427    TestArrayOfActor();
    428    TestUnion();
    429    TestArrayOfUnion();
    430    TestUnionWithArray();
    431    TestArrayOfUnionWithArray();
    432    TestStructWithActor();
    433    TestUnionWithActors();
    434    TestArrayOfUnionWithActors();
    435    TestUnions();
    436    TestArrayOfUnions();
    437    TestStruct();
    438    TestStructWithArrays();
    439    TestStructWithActors();
    440    TestStructs();
    441    TestUnionWithStructs();
    442    TestStructWithUnions();
    443    TestUnionWithCxx();
    444    TestNsIntRegion();
    445 
    446    auto actors = kidsDirect.Clone();
    447    for (auto& actor : actors) {
    448      EXPECT_TRUE(PTestDataStructuresSubChild::Send__delete__(actor));
    449    }
    450 
    451    Close();
    452 
    453    return IPC_OK();
    454  }
    455 
    456  void TestArrayOfInt() {
    457    nsTArray<int> ia;
    458 
    459    for (int i = 0; i < 5; ++i) ia.AppendElement(i);
    460 
    461    nsTArray<int> oa;
    462    EXPECT_TRUE(SendTestArrayOfInt(ia, &oa));
    463 
    464    EXPECT_EQ(ia, oa);
    465  }
    466 
    467  void TestArrayOfActor() {
    468    nsTArray<NotNull<PTestDataStructuresSubChild*>> oa;
    469    EXPECT_TRUE(SendTestArrayOfActor(kidsDirect, &oa));
    470    EXPECT_EQ(kidsDirect, oa);
    471  }
    472 
    473  void TestUnion() {
    474    int i1i = 42;
    475    double i2d = 4.0;
    476    IntDouble i1(i1i);
    477    IntDouble i2(i2d);
    478    IntDouble o1, o2;
    479 
    480    SendTestUnion(i1, i2, &o1, &o2);
    481 
    482    EXPECT_EQ(i1i, o1.get_int());
    483    EXPECT_EQ(i2d, o2.get_double());
    484  }
    485 
    486  void TestArrayOfUnion() {
    487    nsTArray<IntDouble> i1;
    488    i1.AppendElement(IntDouble(int(1)));
    489    i1.AppendElement(IntDouble(2.0));
    490    i1.AppendElement(IntDouble(int(3)));
    491    i1.AppendElement(IntDouble(4.0));
    492 
    493    nsTArray<IntDouble> o1;
    494    EXPECT_TRUE(SendTestArrayOfUnion(i1, &o1));
    495 
    496    // TODO Union::operator==()
    497    EXPECT_EQ(i1.Length(), o1.Length());
    498    EXPECT_EQ(1, o1[0].get_int());
    499    EXPECT_EQ(2.0, o1[1].get_double());
    500    EXPECT_EQ(3, o1[2].get_int());
    501    EXPECT_EQ(4.0, o1[3].get_double());
    502  }
    503 
    504  void TestUnionWithArray() {
    505    IntDoubleArrays i1(int(42));
    506    nsTArray<int> i2;
    507    i2.AppendElement(1);
    508    i2.AppendElement(2);
    509    i2.AppendElement(3);
    510    nsTArray<double> i3;
    511    i3.AppendElement(1.0);
    512    i3.AppendElement(2.0);
    513    i3.AppendElement(3.0);
    514 
    515    IntDoubleArrays o1, o2, o3;
    516    EXPECT_TRUE(SendTestUnionWithArray(i1, IntDoubleArrays(i2),
    517                                       IntDoubleArrays(i3), &o1, &o2, &o3));
    518 
    519    EXPECT_EQ(42, o1.get_int());
    520    EXPECT_EQ(i2, o2.get_ArrayOfint());
    521    EXPECT_EQ(i3, o3.get_ArrayOfdouble());
    522  }
    523 
    524  void TestArrayOfUnionWithArray() {
    525    IntDoubleArrays id1(int(42));
    526    nsTArray<int> id2;
    527    id2.AppendElement(1);
    528    id2.AppendElement(2);
    529    id2.AppendElement(3);
    530    nsTArray<double> id3;
    531    id3.AppendElement(1.0);
    532    id3.AppendElement(2.0);
    533    id3.AppendElement(3.0);
    534 
    535    nsTArray<IntDoubleArrays> i1;
    536    i1.AppendElement(id1);
    537    i1.AppendElement(IntDoubleArrays(id2));
    538    i1.AppendElement(IntDoubleArrays(id3));
    539 
    540    nsTArray<IntDoubleArrays> o1;
    541    EXPECT_TRUE(SendTestArrayOfUnionWithArray(i1, &o1));
    542 
    543    EXPECT_EQ(3u, o1.Length());
    544    IntDoubleArrays od1(o1[0]);
    545    nsTArray<int> od2 = o1[1].get_ArrayOfint().Clone();
    546    nsTArray<double> od3 = o1[2].get_ArrayOfdouble().Clone();
    547 
    548    EXPECT_EQ(42, od1.get_int());
    549    EXPECT_EQ(id2, od2);
    550    EXPECT_EQ(id3, od3);
    551  }
    552 
    553  void TestStructWithActor() {
    554    ActorWrapper iaw(kidsDirect[0]);
    555 
    556    ActorWrapper oaw;
    557    EXPECT_TRUE(SendTestStructWithActor(iaw, &oaw));
    558 
    559    EXPECT_TRUE(oaw.actor().IsChild());
    560    EXPECT_EQ(oaw.actor().AsChild(), kidsDirect[0]);
    561  }
    562 
    563  void TestUnionWithActors() {
    564    Actors i1(42);
    565    nsTArray<int> i2a;
    566    i2a.AppendElement(1);
    567    i2a.AppendElement(2);
    568    i2a.AppendElement(3);
    569 
    570    Actors o1, o2, o3;
    571    EXPECT_TRUE(
    572        SendTestUnionWithActors(i1, Actors(i2a), Actors(kids), &o1, &o2, &o3));
    573 
    574    EXPECT_EQ(42, o1.get_int());
    575    EXPECT_EQ(i2a, o2.get_ArrayOfint());
    576    EXPECT_EQ(kids, o3.get_ArrayOfPTestDataStructuresSub());
    577  }
    578 
    579  void TestArrayOfUnionWithActors() {
    580    Actors i1e(42);
    581    nsTArray<int> i2a;
    582    i2a.AppendElement(1);
    583    i2a.AppendElement(2);
    584    i2a.AppendElement(3);
    585 
    586    nsTArray<Actors> i1;
    587    i1.AppendElement(i1e);
    588    i1.AppendElement(i2a);
    589    i1.AppendElement(kids);
    590 
    591    nsTArray<Actors> o1;
    592    EXPECT_TRUE(SendTestArrayOfUnionWithActors(i1, &o1));
    593 
    594    EXPECT_EQ(3u, o1.Length());
    595    EXPECT_EQ(42, o1[0].get_int());
    596    EXPECT_EQ(i2a, o1[1].get_ArrayOfint());
    597    EXPECT_EQ(kids, o1[2].get_ArrayOfPTestDataStructuresSub());
    598  }
    599 
    600  void TestUnions() {
    601    Unions i1(int(42));
    602 
    603    nsTArray<int> i2a;
    604    i2a.AppendElement(1);
    605    i2a.AppendElement(2);
    606    i2a.AppendElement(3);
    607 
    608    nsTArray<Actors> i4a;
    609    i4a.AppendElement(kids);
    610 
    611    Unions o1, o2, o3, o4;
    612    EXPECT_TRUE(SendTestUnions(i1, Unions(i2a), Unions(kids), Unions(i4a), &o1,
    613                               &o2, &o3, &o4));
    614 
    615    EXPECT_EQ(42, o1.get_int());
    616    EXPECT_EQ(i2a, o2.get_ArrayOfint());
    617    EXPECT_EQ(kids, o3.get_ArrayOfPTestDataStructuresSub());
    618    EXPECT_EQ(kids,
    619              o4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
    620  }
    621 
    622  void TestArrayOfUnions() {
    623    Unions i1a(int(42));
    624 
    625    nsTArray<int> i2a;
    626    i2a.AppendElement(1);
    627    i2a.AppendElement(2);
    628    i2a.AppendElement(3);
    629 
    630    nsTArray<Actors> i4a;
    631    i4a.AppendElement(kids);
    632 
    633    nsTArray<Unions> i1;
    634    i1.AppendElement(i1a);
    635    i1.AppendElement(Unions(i2a));
    636    i1.AppendElement(Unions(kids));
    637    i1.AppendElement(Unions(i4a));
    638 
    639    nsTArray<Unions> o1;
    640    EXPECT_TRUE(SendTestArrayOfUnions(i1, &o1));
    641 
    642    EXPECT_EQ(4u, o1.Length());
    643    EXPECT_EQ(42, o1[0].get_int());
    644    EXPECT_EQ(i2a, o1[1].get_ArrayOfint());
    645    EXPECT_EQ(kids, o1[2].get_ArrayOfPTestDataStructuresSub());
    646    EXPECT_EQ(kids,
    647              o1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
    648  }
    649 
    650  void TestStruct() {
    651    SIntDouble i(1, 2.0);
    652    SIntDouble o;
    653 
    654    EXPECT_TRUE(SendTestStruct(i, &o));
    655 
    656    EXPECT_EQ(o.i(), 1);
    657    EXPECT_EQ(o.d(), 2.0);
    658  }
    659 
    660  void TestStructWithArrays() {
    661    nsTArray<int> ai;
    662    ai.AppendElement(1);
    663    ai.AppendElement(2);
    664    ai.AppendElement(3);
    665 
    666    nsTArray<double> ad;
    667    ad.AppendElement(.5);
    668    ad.AppendElement(1.0);
    669    ad.AppendElement(2.0);
    670 
    671    SIntDoubleArrays i(42, ai, ad);
    672    SIntDoubleArrays o;
    673 
    674    EXPECT_TRUE(SendTestStructWithArrays(i, &o));
    675 
    676    EXPECT_EQ(42, o.i());
    677    EXPECT_EQ(ai, o.ai());
    678    EXPECT_EQ(ad, o.ad());
    679  }
    680 
    681  void TestStructWithActors() {
    682    nsTArray<int> ai;
    683    ai.AppendElement(1);
    684    ai.AppendElement(2);
    685    ai.AppendElement(3);
    686 
    687    SActors i;
    688    i.i() = 42;
    689    i.ai() = ai.Clone();
    690    i.ap() = kids.Clone();
    691 
    692    SActors o;
    693    EXPECT_TRUE(SendTestStructWithActors(i, &o));
    694 
    695    EXPECT_EQ(42, o.i());
    696    EXPECT_EQ(ai, o.ai());
    697    EXPECT_EQ(kids, o.ap());
    698  }
    699 
    700  void TestStructs() {
    701    nsTArray<int> ai;
    702    ai.AppendElement(1);
    703    ai.AppendElement(2);
    704    ai.AppendElement(3);
    705 
    706    SActors ia;
    707    ia.i() = 42;
    708    ia.ai() = ai.Clone();
    709    ia.ap() = kids.Clone();
    710    nsTArray<SActors> aa;
    711    aa.AppendElement(ia);
    712 
    713    Structs i;
    714    i.i() = 42;
    715    i.ai() = ai.Clone();
    716    i.ap() = kids.Clone();
    717    i.aa() = aa.Clone();
    718 
    719    Structs o;
    720    EXPECT_TRUE(SendTestStructs(i, &o));
    721 
    722    EXPECT_EQ(42, o.i());
    723    EXPECT_EQ(ai, o.ai());
    724    EXPECT_EQ(kids, o.ap());
    725 
    726    const SActors& os = o.aa()[0];
    727    EXPECT_EQ(42, os.i());
    728    EXPECT_EQ(ai, os.ai());
    729    EXPECT_EQ(kids, os.ap());
    730  }
    731 
    732  void TestUnionWithStructs() {
    733    nsTArray<int> ai;
    734    ai.AppendElement(1);
    735    ai.AppendElement(2);
    736    ai.AppendElement(3);
    737 
    738    SActors ia;
    739    ia.i() = 42;
    740    ia.ai() = ai.Clone();
    741    ia.ap() = kids.Clone();
    742    nsTArray<SActors> iaa;
    743    iaa.AppendElement(ia);
    744 
    745    Structs is;
    746    is.i() = 42;
    747    is.ai() = ai.Clone();
    748    is.ap() = kids.Clone();
    749    is.aa() = iaa.Clone();
    750    nsTArray<Structs> isa;
    751    isa.AppendElement(is);
    752 
    753    WithStructs o1, o2, o3, o4, o5;
    754    EXPECT_TRUE(SendTestUnionWithStructs(
    755        WithStructs(42), WithStructs(ai), WithStructs(kids), WithStructs(iaa),
    756        WithStructs(isa), &o1, &o2, &o3, &o4, &o5));
    757 
    758    EXPECT_EQ(o1, int(42));
    759    EXPECT_EQ(o2.get_ArrayOfint(), ai);
    760    EXPECT_EQ(o3.get_ArrayOfPTestDataStructuresSub(), kids);
    761 
    762    const SActors& oa = o4.get_ArrayOfSActors()[0];
    763    EXPECT_EQ(42, oa.i());
    764    EXPECT_EQ(ai, oa.ai());
    765    EXPECT_EQ(kids, oa.ap());
    766 
    767    const Structs& os = o5.get_ArrayOfStructs()[0];
    768    EXPECT_EQ(42, os.i());
    769    EXPECT_EQ(ai, os.ai());
    770    EXPECT_EQ(kids, os.ap());
    771 
    772    const SActors& osa = os.aa()[0];
    773    EXPECT_EQ(42, osa.i());
    774    EXPECT_EQ(ai, osa.ai());
    775    EXPECT_EQ(kids, osa.ap());
    776  }
    777 
    778  void TestStructWithUnions() {
    779    WithUnions i;
    780 
    781    i.i() = 42;
    782 
    783    nsTArray<int> ai;
    784    ai.AppendElement(1);
    785    ai.AppendElement(2);
    786    ai.AppendElement(3);
    787    i.ai() = ai.Clone();
    788 
    789    i.ap() = kids.Clone();
    790 
    791    nsTArray<Actors> iaa;
    792    iaa.AppendElement(kids);
    793    i.aa() = iaa.Clone();
    794 
    795    nsTArray<Unions> iau;
    796    iau.AppendElement(int(42));
    797    iau.AppendElement(ai);
    798    iau.AppendElement(kids);
    799    iau.AppendElement(iaa);
    800    i.au() = iau.Clone();
    801 
    802    WithUnions o;
    803    EXPECT_TRUE(SendTestStructWithUnions(i, &o));
    804 
    805    EXPECT_EQ(42, o.i());
    806    EXPECT_EQ(o.ai(), ai);
    807    EXPECT_EQ(o.ap(), kids);
    808 
    809    const Actors& oaa = o.aa()[0];
    810    EXPECT_EQ(oaa.get_ArrayOfPTestDataStructuresSub(), kids);
    811 
    812    const nsTArray<Unions>& oau = o.au();
    813    EXPECT_EQ(oau[0], 42);
    814    EXPECT_EQ(oau[1].get_ArrayOfint(), ai);
    815    EXPECT_EQ(oau[2].get_ArrayOfPTestDataStructuresSub(), kids);
    816    EXPECT_EQ(oau[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub(),
    817              kids);
    818  }
    819 
    820  void TestUnionWithCxx() {
    821    Attrs attrs;
    822    attrs.common() = CommonAttrs(true);
    823    attrs.specific() = BarAttrs(1.0f);
    824 
    825    nsTArray<Op> ops;
    826    ops.AppendElement(SetAttrs(kids[0], attrs));
    827 
    828    EXPECT_TRUE(SendTestUnionWithCxx(ops));
    829  }
    830 
    831  void TestNsIntRegion() {
    832    const int nelements = 1000;
    833    RegionArray ra;
    834    // big enough to hopefully force a realloc to a different chunk of
    835    // memory on the receiving side, if the workaround isn't working
    836    // correctly.  But SetCapacity() here because we don't want to
    837    // crash on the sending side.
    838    ra.SetCapacity(nelements);
    839    for (int i = 0; i < nelements; ++i) {
    840      nsIntRegion r;
    841      r.Or(nsIntRect(0, 0, 10, 10), nsIntRect(10, 10, 10, 10));
    842      ra.AppendElement(r);
    843    }
    844 
    845    EXPECT_TRUE(SendTestNsIntRegion(ra));
    846  }
    847 
    848  ~TestDataStructuresChild() = default;
    849 };
    850 
    851 IPDL_TEST(TestDataStructures) {
    852  for (uint32_t i = 0; i < nactors; ++i) {
    853    auto sub = MakeRefPtr<TestDataStructuresSubParent>(i);
    854    EXPECT_TRUE(mActor->SendPTestDataStructuresSubConstructor(sub, i))
    855        << "can't alloc actor";
    856    mActor->kids.AppendElement(WrapNotNull(sub));
    857  }
    858 
    859  EXPECT_TRUE(mActor->SendStart()) << "can't send Start()";
    860 }
    861 
    862 }  // namespace mozilla::_ipdltest