1 #include "TestDataStructures.h"
2 
3 #include "mozilla/Unused.h"
4 
5 #include "IPDLUnitTests.h"      // fail etc.
6 
7 typedef InfallibleTArray<nsIntRegion> RegionArray;
8 
9 namespace mozilla {
10 namespace _ipdltest {
11 
12 static const uint32_t nactors = 10;
13 
14 #define test_assert(_cond, _msg) \
15     if (!(_cond)) fail(_msg)
16 
17 template<typename T>
18 static void
19 assert_arrays_equal(const InfallibleTArray<T>& a, const InfallibleTArray<T>& b)
20 {
21     test_assert(a == b, "arrays equal");
22 }
23 
24 inline static TestDataStructuresSub&
25 Cast(PTestDataStructuresSubParent* a)
26 {
27     return *static_cast<TestDataStructuresSub*>(a);
28 }
29 
30 inline static TestDataStructuresSub&
31 Cast(PTestDataStructuresSubChild* a)
32 {
33     return *static_cast<TestDataStructuresSub*>(a);
34 }
35 
36 //-----------------------------------------------------------------------------
37 // parent
38 
39 TestDataStructuresParent::TestDataStructuresParent()
40 {
41     MOZ_COUNT_CTOR(TestDataStructuresParent);
42 }
43 
44 TestDataStructuresParent::~TestDataStructuresParent()
45 {
46     MOZ_COUNT_DTOR(TestDataStructuresParent);
47 }
48 
49 void
50 TestDataStructuresParent::Main()
51 {
52     for (uint32_t i = 0; i < nactors; ++i)
53         if (!SendPTestDataStructuresSubConstructor(i))
54             fail("can't alloc actor");
55 
56     if (!SendStart())
57         fail("can't send Start()");
58 }
59 
60 bool
61 TestDataStructuresParent::DeallocPTestDataStructuresSubParent(PTestDataStructuresSubParent* actor)
62 {
63     test_assert(Cast(actor).mI == Cast(mKids[0]).mI,
64                 "dtor sent to wrong actor");
65     mKids.RemoveElementAt(0);
66     delete actor;
67     if (mKids.Length() > 0)
68         return true;
69 
70     return true;
71 }
72 
73 bool TestDataStructuresParent::RecvTest1(
74         InfallibleTArray<int>&& ia,
75         InfallibleTArray<int>* oa)
76 {
77     test_assert(5 == ia.Length(), "wrong length");
78     for (int i = 0; i < 5; ++i)
79         test_assert(i == ia[i], "wrong value");
80 
81     *oa = ia;
82 
83     return true;
84 }
85 
86 bool TestDataStructuresParent::RecvTest2(
87         InfallibleTArray<PTestDataStructuresSubParent*>&& i1,
88         InfallibleTArray<PTestDataStructuresSubParent*>* o1)
89 {
90     test_assert(nactors == i1.Length(), "wrong #actors");
91     for (uint32_t i = 0; i < i1.Length(); ++i)
92         test_assert(i == Cast(i1[i]).mI, "wrong mI value");
93     *o1 = i1;
94     return true;
95 }
96 
97 bool TestDataStructuresParent::RecvTest3(
98         const IntDouble& i1,
99         const IntDouble& i2,
100         IntDouble* o1,
101         IntDouble* o2)
102 {
103     test_assert(42 == i1.get_int(), "wrong value");
104     test_assert(4.0 == i2.get_double(), "wrong value");
105 
106     *o1 = i1;
107     *o2 = i2;
108 
109     return true;
110 }
111 
112 bool TestDataStructuresParent::RecvTest4(
113         InfallibleTArray<IntDouble>&& i1,
114         InfallibleTArray<IntDouble>* o1)
115 {
116     test_assert(4 == i1.Length(), "wrong length");
117     test_assert(1 == i1[0].get_int(), "wrong value");
118     test_assert(2.0 == i1[1].get_double(), "wrong value");
119     test_assert(3 == i1[2].get_int(), "wrong value");
120     test_assert(4.0 == i1[3].get_double(), "wrong value");
121 
122     *o1 = i1;
123 
124     return true;
125 }
126 
127 bool TestDataStructuresParent::RecvTest5(
128         const IntDoubleArrays& i1,
129         const IntDoubleArrays& i2,
130         const IntDoubleArrays& i3,
131         IntDoubleArrays* o1,
132         IntDoubleArrays* o2,
133         IntDoubleArrays* o3)
134 {
135     test_assert(42 == i1.get_int(), "wrong value");
136 
137     const InfallibleTArray<int>& i2a = i2.get_ArrayOfint();
138     test_assert(3 == i2a.Length(), "wrong length");
139     test_assert(1 == i2a[0], "wrong value");
140     test_assert(2 == i2a[1], "wrong value");
141     test_assert(3 == i2a[2], "wrong value");
142 
143     const InfallibleTArray<double>& i3a = i3.get_ArrayOfdouble();
144     test_assert(3 == i3a.Length(), "wrong length");
145     test_assert(1.0 == i3a[0], "wrong value");
146     test_assert(2.0 == i3a[1], "wrong value");
147     test_assert(3.0 == i3a[2], "wrong value");
148 
149     *o1 = i1;
150     *o2 = i2a;
151     *o3 = i3a;
152 
153     return true;
154 }
155 
156 bool
157 TestDataStructuresParent::RecvTest7_0(const ActorWrapper& i1,
158                                       ActorWrapper* o1)
159 {
160     if (i1.actorChild() != nullptr)
161         fail("child side actor should always be null");
162 
163     if (i1.actorParent() != mKids[0])
164         fail("should have got back same actor on parent side");
165 
166     o1->actorParent() = mKids[0];
167     // malicious behavior
168     o1->actorChild() =
169         reinterpret_cast<PTestDataStructuresSubChild*>(uintptr_t(0xdeadbeef));
170     return true;
171 }
172 
173 bool TestDataStructuresParent::RecvTest6(
174         InfallibleTArray<IntDoubleArrays>&& i1,
175         InfallibleTArray<IntDoubleArrays>* o1)
176 {
177     test_assert(3 == i1.Length(), "wrong length");
178 
179     IntDoubleArrays id1(i1[0]);
180     test_assert(42 == id1.get_int(), "wrong value");
181 
182     InfallibleTArray<int> i2a(i1[1].get_ArrayOfint());
183     test_assert(3 == i2a.Length(), "wrong length");
184     test_assert(1 == i2a[0], "wrong value");
185     test_assert(2 == i2a[1], "wrong value");
186     test_assert(3 == i2a[2], "wrong value");
187 
188     InfallibleTArray<double> i3a(i1[2].get_ArrayOfdouble());
189     test_assert(3 == i3a.Length(), "wrong length");
190     test_assert(1.0 == i3a[0], "wrong value");
191     test_assert(2.0 == i3a[1], "wrong value");
192     test_assert(3.0 == i3a[2], "wrong value");
193 
194     o1->AppendElement(id1);
195     o1->AppendElement(IntDoubleArrays(i2a));
196     o1->AppendElement(IntDoubleArrays(i3a));
197 
198     return true;
199 }
200 
201 bool TestDataStructuresParent::RecvTest7(
202         const Actors& i1,
203         const Actors& i2,
204         const Actors& i3,
205         Actors* o1,
206         Actors* o2,
207         Actors* o3)
208 {
209     test_assert(42 == i1.get_int(), "wrong value");
210 
211     InfallibleTArray<int> i2a(i2.get_ArrayOfint());
212     test_assert(3 == i2a.Length(), "wrong length");
213     test_assert(1 == i2a[0], "wrong value");
214     test_assert(2 == i2a[1], "wrong value");
215     test_assert(3 == i2a[2], "wrong value");
216 
217     assert_arrays_equal(mKids, i3.get_ArrayOfPTestDataStructuresSubParent());
218 
219     *o1 = 42;
220     *o2 = i2a;
221     *o3 = mKids;
222 
223     return true;
224 }
225 
226 bool TestDataStructuresParent::RecvTest8(
227         InfallibleTArray<Actors>&& i1,
228         InfallibleTArray<Actors>* o1)
229 {
230     test_assert(3 == i1.Length(), "wrong length");
231     test_assert(42 == i1[0].get_int(), "wrong value");
232 
233     const InfallibleTArray<int>& i2a = i1[1].get_ArrayOfint();
234     test_assert(3 == i2a.Length(), "wrong length");
235     test_assert(1 == i2a[0], "wrong value");
236     test_assert(2 == i2a[1], "wrong value");
237     test_assert(3 == i2a[2], "wrong value");
238 
239     assert_arrays_equal(mKids, i1[2].get_ArrayOfPTestDataStructuresSubParent());
240 
241     *o1 = i1;
242 
243     return true;
244 }
245 
246 bool TestDataStructuresParent::RecvTest9(
247         const Unions& i1,
248         const Unions& i2,
249         const Unions& i3,
250         const Unions& i4,
251         Unions* o1,
252         Unions* o2,
253         Unions* o3,
254         Unions* o4)
255 {
256     test_assert(42 == i1.get_int(), "wrong value");
257 
258     const InfallibleTArray<int>& i2a = i2.get_ArrayOfint();
259     test_assert(3 == i2a.Length(), "wrong length");
260     test_assert(1 == i2a[0], "wrong value");
261     test_assert(2 == i2a[1], "wrong value");
262     test_assert(3 == i2a[2], "wrong value");
263 
264     assert_arrays_equal(mKids, i3.get_ArrayOfPTestDataStructuresSubParent());
265 
266     const InfallibleTArray<PTestDataStructuresSubParent*>& i4a =
267         i4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSubParent();
268     assert_arrays_equal(mKids, i4a);
269 
270     *o1 = i1;
271     *o2 = i2;
272     *o3 = i3;
273     *o4 = i4;
274 
275     return true;
276 }
277 
278 bool TestDataStructuresParent::RecvTest10(
279         InfallibleTArray<Unions>&& i1,
280         InfallibleTArray<Unions>* o1)
281 {
282     test_assert(42 == i1[0].get_int(), "wrong value");
283 
284     const InfallibleTArray<int>& i2a = i1[1].get_ArrayOfint();
285     test_assert(3 == i2a.Length(), "wrong length");
286     test_assert(1 == i2a[0], "wrong value");
287     test_assert(2 == i2a[1], "wrong value");
288     test_assert(3 == i2a[2], "wrong value");
289 
290     assert_arrays_equal(mKids, i1[2].get_ArrayOfPTestDataStructuresSubParent());
291 
292     const InfallibleTArray<PTestDataStructuresSubParent*>& i4a =
293         i1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSubParent();
294     assert_arrays_equal(mKids, i4a);
295 
296     *o1 = i1;
297 
298     return true;
299 }
300 
301 bool TestDataStructuresParent::RecvTest11(
302             const SIntDouble& i,
303             SIntDouble* o)
304 {
305     test_assert(1 == i.i(), "wrong value");
306     test_assert(2.0 == i.d(), "wrong value");
307     *o = i;
308     return true;
309 }
310 
311 bool TestDataStructuresParent::RecvTest12(
312             const SIntDoubleArrays& i,
313             SIntDoubleArrays* o)
314 {
315     InfallibleTArray<int> ai;
316     ai.AppendElement(1);
317     ai.AppendElement(2);
318     ai.AppendElement(3);
319 
320     InfallibleTArray<double> ad;
321     ad.AppendElement(.5);
322     ad.AppendElement(1.0);
323     ad.AppendElement(2.0);
324 
325     test_assert(42 == i.i(), "wrong value");
326     assert_arrays_equal(ai, i.ai());
327     assert_arrays_equal(ad, i.ad());
328 
329     *o = i;
330 
331     return true;
332 }
333 
334 bool TestDataStructuresParent::RecvTest13(
335             const SActors& i,
336             SActors* o)
337 {
338     InfallibleTArray<int> ai;
339     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
340 
341     test_assert(42 == i.i(), "wrong value");
342     assert_arrays_equal(ai, i.ai());
343     assert_arrays_equal(mKids, i.apParent());
344 
345     *o = i;
346 
347     return true;
348 }
349 
350 bool TestDataStructuresParent::RecvTest14(
351             const Structs& i,
352             Structs* o)
353 {
354     InfallibleTArray<int> ai;
355     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
356 
357     test_assert(42 == i.i(), "wrong value");
358     assert_arrays_equal(ai, i.ai());
359     assert_arrays_equal(mKids, i.apParent());
360 
361     const SActors& ia = i.aa()[0];
362     test_assert(42 == ia.i(), "wrong value");
363     assert_arrays_equal(ai, ia.ai());
364     assert_arrays_equal(mKids, ia.apParent());
365 
366     *o = i;
367 
368     return true;
369 }
370 
371 bool TestDataStructuresParent::RecvTest15(
372             const WithStructs& i1,
373             const WithStructs& i2,
374             const WithStructs& i3,
375             const WithStructs& i4,
376             const WithStructs& i5,
377             WithStructs* o1,
378             WithStructs* o2,
379             WithStructs* o3,
380             WithStructs* o4,
381             WithStructs* o5)
382 {
383     InfallibleTArray<int> ai;
384     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
385 
386     test_assert(i1 == int(42), "wrong value");
387     assert_arrays_equal(i2.get_ArrayOfint(), ai);
388     assert_arrays_equal(i3.get_ArrayOfPTestDataStructuresSubParent(), mKids);
389 
390     const SActors& ia = i4.get_ArrayOfSActors()[0];
391     test_assert(42 == ia.i(), "wrong value");
392     assert_arrays_equal(ai, ia.ai());
393     assert_arrays_equal(mKids, ia.apParent());
394 
395     const Structs& is = i5.get_ArrayOfStructs()[0];
396     test_assert(42 == is.i(), "wrong value");
397     assert_arrays_equal(ai, is.ai());
398     assert_arrays_equal(mKids, is.apParent());
399 
400     const SActors& isa = is.aa()[0];
401     test_assert(42 == isa.i(), "wrong value");
402     assert_arrays_equal(ai, isa.ai());
403     assert_arrays_equal(mKids, isa.apParent());
404 
405     *o1 = i1;
406     *o2 = i2;
407     *o3 = i3;
408     *o4 = i4;
409     *o5 = i5;
410 
411     return true;
412 }
413 
414 bool TestDataStructuresParent::RecvTest16(
415             const WithUnions& i,
416             WithUnions* o)
417 {
418     test_assert(i.i() == 42, "wrong value");
419 
420     InfallibleTArray<int> ai;
421     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
422     assert_arrays_equal(ai, i.ai());
423 
424     assert_arrays_equal(i.apParent(), mKids);
425 
426     assert_arrays_equal(mKids, i.aa()[0].get_ArrayOfPTestDataStructuresSubParent());
427 
428     const InfallibleTArray<Unions>& iau = i.au();
429     test_assert(iau[0] == 42, "wrong value");
430     assert_arrays_equal(ai, iau[1].get_ArrayOfint());
431     assert_arrays_equal(mKids, iau[2].get_ArrayOfPTestDataStructuresSubParent());
432     assert_arrays_equal(mKids,
433                         iau[3].get_ArrayOfActors()[0]
434                         .get_ArrayOfPTestDataStructuresSubParent());
435 
436     *o = i;
437 
438     return true;
439 }
440 
441 bool TestDataStructuresParent::RecvTest17(InfallibleTArray<Op>&& sa)
442 {
443     test_assert(sa.Length() == 1 && Op::TSetAttrs == sa[0].type(),
444                 "wrong value");
445     return true;
446 }
447 
448 bool TestDataStructuresParent::RecvTest18(RegionArray&& ra)
449 {
450     for (RegionArray::index_type i = 0; i < ra.Length(); ++i) {
451         // if |ra| has been realloc()d and given a different allocator
452         // chunk, this loop will nondeterministically crash or iloop.
453         for (auto iter = ra[i].RectIter(); !iter.Done(); iter.Next()) {
454             Unused << iter.Get();
455         }
456     }
457     return true;
458 }
459 
460 //-----------------------------------------------------------------------------
461 // child
462 
463 TestDataStructuresChild::TestDataStructuresChild()
464 {
465     MOZ_COUNT_CTOR(TestDataStructuresChild);
466 }
467 
468 TestDataStructuresChild::~TestDataStructuresChild()
469 {
470     MOZ_COUNT_DTOR(TestDataStructuresChild);
471 }
472 
473 bool
474 TestDataStructuresChild::RecvStart()
475 {
476     puts("[TestDataStructuresChild] starting");
477 
478     Test1();
479     Test2();
480     Test3();
481     Test4();
482     Test5();
483     Test6();
484     Test7_0();
485     Test7();
486     Test8();
487     Test9();
488     Test10();
489     Test11();
490     Test12();
491     Test13();
492     Test14();
493     Test15();
494     Test16();
495     Test17();
496     if (OtherPid() != base::GetCurrentProcId()) {
497         //FIXME/bug 703317 allocation of nsIntRegion uses a global
498         //region pool which breaks threads
499         Test18();
500     }
501 
502     for (uint32_t i = 0; i < nactors; ++i)
503         if (!PTestDataStructuresSubChild::Send__delete__(mKids[i]))
504             fail("can't send dtor");
505 
506     Close();
507 
508     return true;
509 }
510 
511 void
512 TestDataStructuresChild::Test1()
513 {
514     InfallibleTArray<int> ia;
515 
516     for (int i = 0; i < 5; ++i)
517         ia.AppendElement(i);
518 
519     InfallibleTArray<int> oa;
520     if (!SendTest1(ia, &oa))
521         fail("can't send Test1");
522 
523     assert_arrays_equal(ia, oa);
524 
525     printf("  passed %s\n", __FUNCTION__);
526 }
527 
528 void
529 TestDataStructuresChild::Test2()
530 {
531     InfallibleTArray<PTestDataStructuresSubChild*> oa;
532     if (!SendTest2(mKids, &oa))
533         fail("can't send Test2");
534     assert_arrays_equal(mKids, oa);
535 
536     printf("  passed %s\n", __FUNCTION__);
537 }
538 
539 void
540 TestDataStructuresChild::Test3()
541 {
542     int i1i = 42;
543     double i2d = 4.0;
544     IntDouble i1(i1i);
545     IntDouble i2(i2d);
546     IntDouble o1, o2;
547 
548     SendTest3(i1, i2, &o1, &o2);
549 
550     test_assert(i1i == o1.get_int(), "wrong value");
551     test_assert(i2d == o2.get_double(), "wrong value");
552 
553     printf("  passed %s\n", __FUNCTION__);
554 }
555 
556 void
557 TestDataStructuresChild::Test4()
558 {
559     InfallibleTArray<IntDouble> i1;
560     i1.AppendElement(IntDouble(int(1)));
561     i1.AppendElement(IntDouble(2.0));
562     i1.AppendElement(IntDouble(int(3)));
563     i1.AppendElement(IntDouble(4.0));
564 
565     InfallibleTArray<IntDouble> o1;
566     if (!SendTest4(i1, &o1))
567         fail("can't send Test4");
568 
569     // TODO Union::operator==()
570     test_assert(i1.Length() == o1.Length(), "wrong length");
571     test_assert(1 == o1[0].get_int(), "wrong value");
572     test_assert(2.0 == o1[1].get_double(), "wrong value");
573     test_assert(3 == o1[2].get_int(), "wrong value");
574     test_assert(4.0 == o1[3].get_double(), "wrong value");
575 
576     printf("  passed %s\n", __FUNCTION__);
577 }
578 
579 void
580 TestDataStructuresChild::Test5()
581 {
582     IntDoubleArrays i1(int(42));
583     InfallibleTArray<int> i2;
584     i2.AppendElement(1); i2.AppendElement(2); i2.AppendElement(3);
585     InfallibleTArray<double> i3;
586     i3.AppendElement(1.0); i3.AppendElement(2.0); i3.AppendElement(3.0);
587 
588     IntDoubleArrays o1, o2, o3;
589     if (!SendTest5(i1, IntDoubleArrays(i2), IntDoubleArrays(i3),
590                    &o1, &o2, &o3))
591         fail("can't send Test5");
592 
593     test_assert(42 == o1.get_int(), "wrong value");
594     assert_arrays_equal(i2, o2.get_ArrayOfint());
595     assert_arrays_equal(i3, o3.get_ArrayOfdouble());
596 
597     printf("  passed %s\n", __FUNCTION__);
598 }
599 
600 void
601 TestDataStructuresChild::Test6()
602 {
603     IntDoubleArrays id1(int(42));
604     InfallibleTArray<int> id2;
605     id2.AppendElement(1); id2.AppendElement(2); id2.AppendElement(3);
606     InfallibleTArray<double> id3;
607     id3.AppendElement(1.0); id3.AppendElement(2.0); id3.AppendElement(3.0);
608 
609     InfallibleTArray<IntDoubleArrays> i1;
610     i1.AppendElement(id1);
611     i1.AppendElement(IntDoubleArrays(id2));
612     i1.AppendElement(IntDoubleArrays(id3));
613 
614     InfallibleTArray<IntDoubleArrays> o1;
615     if (!SendTest6(i1, &o1))
616         fail("can't send Test6");
617 
618     test_assert(3 == o1.Length(), "wrong length");
619     IntDoubleArrays od1(o1[0]);
620     InfallibleTArray<int> od2(o1[1].get_ArrayOfint());
621     InfallibleTArray<double> od3(o1[2].get_ArrayOfdouble());
622 
623     test_assert(42 == od1.get_int(), "wrong value");
624     assert_arrays_equal(id2, od2);
625     assert_arrays_equal(id3, od3);
626 
627     printf("  passed %s\n", __FUNCTION__);
628 }
629 
630 void
631 TestDataStructuresChild::Test7_0()
632 {
633     ActorWrapper iaw;
634     if (iaw.actorChild() != nullptr || iaw.actorParent() != nullptr)
635         fail("actor members should be null initially");
636 
637     iaw.actorChild() = mKids[0];
638     if (iaw.actorParent() != nullptr)
639         fail("parent should be null on child side after set");
640 
641     ActorWrapper oaw;
642     if (!SendTest7_0(iaw, &oaw))
643         fail("sending Test7_0");
644 
645     if (oaw.actorParent() != nullptr)
646         fail("parent accessor on actor-struct members should always be null in child");
647 
648     if (oaw.actorChild() != mKids[0])
649         fail("should have got back same child-side actor");
650 }
651 
652 void
653 TestDataStructuresChild::Test7()
654 {
655     Actors i1(42);
656     InfallibleTArray<int> i2a;
657     i2a.AppendElement(1);  i2a.AppendElement(2);  i2a.AppendElement(3);
658 
659     Actors o1, o2, o3;
660     if (!SendTest7(i1, Actors(i2a), Actors(mKids), &o1, &o2, &o3))
661         fail("can't send Test7");
662 
663     test_assert(42 == o1.get_int(), "wrong value");
664     assert_arrays_equal(i2a, o2.get_ArrayOfint());
665     assert_arrays_equal(mKids, o3.get_ArrayOfPTestDataStructuresSubChild());
666 
667     printf("  passed %s\n", __FUNCTION__);
668 }
669 
670 void
671 TestDataStructuresChild::Test8()
672 {
673     Actors i1e(42);
674     InfallibleTArray<int> i2a;
675     i2a.AppendElement(1);  i2a.AppendElement(2);  i2a.AppendElement(3);
676 
677     InfallibleTArray<Actors> i1;
678     i1.AppendElement(i1e);
679     i1.AppendElement(i2a);
680     i1.AppendElement(mKids);
681 
682     InfallibleTArray<Actors> o1;
683     if (!SendTest8(i1, &o1))
684         fail("can't send Test8");
685 
686     test_assert(3 == o1.Length(), "wrong length");
687     test_assert(42 == o1[0].get_int(), "wrong value");
688     assert_arrays_equal(i2a, o1[1].get_ArrayOfint());
689     assert_arrays_equal(mKids, o1[2].get_ArrayOfPTestDataStructuresSubChild());
690 
691     printf("  passed %s\n", __FUNCTION__);
692 }
693 
694 void
695 TestDataStructuresChild::Test9()
696 {
697     Unions i1(int(42));
698 
699     InfallibleTArray<int> i2a;
700     i2a.AppendElement(1);
701     i2a.AppendElement(2);
702     i2a.AppendElement(3);
703 
704     InfallibleTArray<Actors> i4a;
705     i4a.AppendElement(mKids);
706 
707     Unions o1, o2, o3, o4;
708     if (!SendTest9(i1, Unions(i2a), Unions(mKids), Unions(i4a),
709                    &o1, &o2, &o3, &o4))
710         fail("can't send Test9");
711 
712     test_assert(42 == o1.get_int(), "wrong value");
713     assert_arrays_equal(i2a, o2.get_ArrayOfint());
714     assert_arrays_equal(mKids, o3.get_ArrayOfPTestDataStructuresSubChild());
715     assert_arrays_equal(
716         mKids,
717         o4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSubChild());
718 
719     printf("  passed %s\n", __FUNCTION__);
720 }
721 
722 void
723 TestDataStructuresChild::Test10()
724 {
725     Unions i1a(int(42));
726 
727     InfallibleTArray<int> i2a;
728     i2a.AppendElement(1);
729     i2a.AppendElement(2);
730     i2a.AppendElement(3);
731 
732     InfallibleTArray<Actors> i4a;
733     i4a.AppendElement(mKids);
734 
735     InfallibleTArray<Unions> i1;
736     i1.AppendElement(i1a);
737     i1.AppendElement(Unions(i2a));
738     i1.AppendElement(Unions(mKids));
739     i1.AppendElement(Unions(i4a));
740 
741     InfallibleTArray<Unions> o1;
742     if (!SendTest10(i1, &o1))
743         fail("can't send Test10");
744 
745     test_assert(4 == o1.Length(), "wrong length");
746     test_assert(42 == o1[0].get_int(), "wrong value");
747     assert_arrays_equal(i2a, o1[1].get_ArrayOfint());
748     assert_arrays_equal(mKids, o1[2].get_ArrayOfPTestDataStructuresSubChild());
749     assert_arrays_equal(
750         mKids,
751         o1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSubChild());
752 
753     printf("  passed %s\n", __FUNCTION__);
754 }
755 
756 void
757 TestDataStructuresChild::Test11()
758 {
759     SIntDouble i(1, 2.0);
760     SIntDouble o;
761 
762     if (!SendTest11(i, &o))
763         fail("sending Test11");
764 
765     test_assert(1 == o.i() && 2.0 == o.d(), "wrong values");
766 
767     printf("  passed %s\n", __FUNCTION__);
768 }
769 
770 void
771 TestDataStructuresChild::Test12()
772 {
773     InfallibleTArray<int> ai;
774     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
775 
776     InfallibleTArray<double> ad;
777     ad.AppendElement(.5);  ad.AppendElement(1.0);  ad.AppendElement(2.0);
778 
779     SIntDoubleArrays i(42, ai, ad);
780     SIntDoubleArrays o;
781 
782     if (!SendTest12(i, &o))
783         fail("sending Test12");
784 
785     test_assert(42 == o.i(), "wrong value");
786     assert_arrays_equal(ai, o.ai());
787     assert_arrays_equal(ad, o.ad());
788 
789     printf("  passed %s\n", __FUNCTION__);
790 }
791 
792 void
793 TestDataStructuresChild::Test13()
794 {
795     InfallibleTArray<int> ai;
796     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
797 
798     SActors i;
799     i.i() = 42;
800     i.ai() = ai;
801     i.apChild() = mKids;
802 
803     SActors o;
804     if (!SendTest13(i, &o))
805         fail("can't send Test13");
806 
807     test_assert(42 == o.i(), "wrong value");
808     assert_arrays_equal(ai, o.ai());
809     assert_arrays_equal(mKids, o.apChild());
810 
811     printf("  passed %s\n", __FUNCTION__);
812 }
813 
814 void
815 TestDataStructuresChild::Test14()
816 {
817     InfallibleTArray<int> ai;
818     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
819 
820     SActors ia;
821     ia.i() = 42;
822     ia.ai() = ai;
823     ia.apChild() = mKids;
824     InfallibleTArray<SActors> aa;  aa.AppendElement(ia);
825 
826     Structs i;
827     i.i() = 42;
828     i.ai() = ai;
829     i.apChild() = mKids;
830     i.aa() = aa;
831 
832     Structs o;
833     if (!SendTest14(i, &o))
834         fail("can't send Test14");
835 
836     test_assert(42 == o.i(), "wrong value");
837     assert_arrays_equal(ai, o.ai());
838     assert_arrays_equal(mKids, o.apChild());
839 
840     const SActors& os = o.aa()[0];
841     test_assert(42 == os.i(), "wrong value");
842     assert_arrays_equal(ai, os.ai());
843     assert_arrays_equal(mKids, os.apChild());
844 
845     printf("  passed %s\n", __FUNCTION__);
846 }
847 
848 void
849 TestDataStructuresChild::Test15()
850 {
851     InfallibleTArray<int> ai;
852     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
853 
854     SActors ia;
855     ia.i() = 42;
856     ia.ai() = ai;
857     ia.apChild() = mKids;
858     InfallibleTArray<SActors> iaa;  iaa.AppendElement(ia);
859 
860     Structs is;
861     is.i() = 42;
862     is.ai() = ai;
863     is.apChild() = mKids;
864     is.aa() = iaa;
865     InfallibleTArray<Structs> isa;  isa.AppendElement(is);
866 
867     WithStructs o1, o2, o3, o4, o5;
868     if (!SendTest15(WithStructs(42),
869                     WithStructs(ai),
870                     WithStructs(mKids),
871                     WithStructs(iaa),
872                     WithStructs(isa),
873                     &o1, &o2, &o3, &o4, &o5))
874         fail("sending Test15");
875 
876     test_assert(o1 == int(42), "wrong value");
877     assert_arrays_equal(o2.get_ArrayOfint(), ai);
878     assert_arrays_equal(o3.get_ArrayOfPTestDataStructuresSubChild(), mKids);
879 
880     const SActors& oa = o4.get_ArrayOfSActors()[0];
881     test_assert(42 == oa.i(), "wrong value");
882     assert_arrays_equal(ai, oa.ai());
883     assert_arrays_equal(mKids, oa.apChild());
884 
885     const Structs& os = o5.get_ArrayOfStructs()[0];
886     test_assert(42 == os.i(), "wrong value");
887     assert_arrays_equal(ai, os.ai());
888     assert_arrays_equal(mKids, os.apChild());
889 
890     const SActors& osa = os.aa()[0];
891     test_assert(42 == osa.i(), "wrong value");
892     assert_arrays_equal(ai, osa.ai());
893     assert_arrays_equal(mKids, osa.apChild());
894 
895     printf("  passed %s\n", __FUNCTION__);
896 }
897 
898 void
899 TestDataStructuresChild::Test16()
900 {
901     WithUnions i;
902 
903     i.i() = 42;
904 
905     InfallibleTArray<int> ai;
906     ai.AppendElement(1);  ai.AppendElement(2);  ai.AppendElement(3);
907     i.ai() = ai;
908 
909     i.apChild() = mKids;
910 
911     InfallibleTArray<Actors> iaa;
912     iaa.AppendElement(mKids);
913     i.aa() = iaa;
914 
915     InfallibleTArray<Unions> iau;
916     iau.AppendElement(int(42));
917     iau.AppendElement(ai);
918     iau.AppendElement(mKids);
919     iau.AppendElement(iaa);
920     i.au() = iau;
921 
922     WithUnions o;
923     if (!SendTest16(i, &o))
924         fail("sending Test16");
925 
926     test_assert(42 == o.i(), "wrong value");
927     assert_arrays_equal(o.ai(), ai);
928     assert_arrays_equal(o.apChild(), mKids);
929 
930     const Actors& oaa = o.aa()[0];
931     assert_arrays_equal(oaa.get_ArrayOfPTestDataStructuresSubChild(), mKids);
932 
933     const InfallibleTArray<Unions>& oau = o.au();
934     test_assert(oau[0] == 42, "wrong value");
935     assert_arrays_equal(oau[1].get_ArrayOfint(), ai);
936     assert_arrays_equal(oau[2].get_ArrayOfPTestDataStructuresSubChild(),
937                         mKids);
938     assert_arrays_equal(oau[3].get_ArrayOfActors()[0]
939                         .get_ArrayOfPTestDataStructuresSubChild(),
940                         mKids);
941 
942     printf("  passed %s\n", __FUNCTION__);
943 }
944 
945 void
946 TestDataStructuresChild::Test17()
947 {
948     Attrs attrs;
949     attrs.common() = CommonAttrs(true);
950     attrs.specific() = BarAttrs(1.0f);
951 
952     InfallibleTArray<Op> ops;
953     ops.AppendElement(SetAttrs(nullptr, mKids[0], attrs));
954 
955     if (!SendTest17(ops))
956         fail("sending Test17");
957 
958     printf("  passed %s\n", __FUNCTION__);
959 }
960 
961 void
962 TestDataStructuresChild::Test18()
963 {
964     const int nelements = 1000;
965     RegionArray ra;
966     // big enough to hopefully force a realloc to a different chunk of
967     // memory on the receiving side, if the workaround isn't working
968     // correctly.  But SetCapacity() here because we don't want to
969     // crash on the sending side.
970     ra.SetCapacity(nelements);
971     for (int i = 0; i < nelements; ++i) {
972         nsIntRegion r;
973         r.Or(nsIntRect(0, 0, 10, 10), nsIntRect(10, 10, 10, 10));
974         ra.AppendElement(r);
975     }
976 
977     if (!SendTest18(ra))
978         fail("sending Test18");
979 
980     printf("  passed %s\n", __FUNCTION__);
981 }
982 
983 } // namespace _ipdltest
984 } // namespace mozilla
985