Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | // Original author: ekr@rtfm.com |
michael@0 | 8 | #include <iostream> |
michael@0 | 9 | |
michael@0 | 10 | #include "prio.h" |
michael@0 | 11 | |
michael@0 | 12 | #include "nsCOMPtr.h" |
michael@0 | 13 | #include "nsNetCID.h" |
michael@0 | 14 | #include "nsXPCOM.h" |
michael@0 | 15 | #include "nsXPCOMGlue.h" |
michael@0 | 16 | |
michael@0 | 17 | #include "mozilla/RefPtr.h" |
michael@0 | 18 | #include "nsIComponentManager.h" |
michael@0 | 19 | #include "nsIComponentRegistrar.h" |
michael@0 | 20 | #include "nsIIOService.h" |
michael@0 | 21 | #include "nsIServiceManager.h" |
michael@0 | 22 | #include "nsISocketTransportService.h" |
michael@0 | 23 | |
michael@0 | 24 | #include "nsASocketHandler.h" |
michael@0 | 25 | #include "nsServiceManagerUtils.h" |
michael@0 | 26 | #include "nsThreadUtils.h" |
michael@0 | 27 | |
michael@0 | 28 | #include "runnable_utils.h" |
michael@0 | 29 | #include "mtransport_test_utils.h" |
michael@0 | 30 | |
michael@0 | 31 | #define GTEST_HAS_RTTI 0 |
michael@0 | 32 | #include "gtest/gtest.h" |
michael@0 | 33 | #include "gtest_utils.h" |
michael@0 | 34 | |
michael@0 | 35 | using namespace mozilla; |
michael@0 | 36 | MtransportTestUtils *test_utils; |
michael@0 | 37 | |
michael@0 | 38 | namespace { |
michael@0 | 39 | |
michael@0 | 40 | class Destructor { |
michael@0 | 41 | public: |
michael@0 | 42 | Destructor(bool* destroyed) : destroyed_(destroyed) {} |
michael@0 | 43 | ~Destructor() { |
michael@0 | 44 | std::cerr << "Destructor called" << std::endl; |
michael@0 | 45 | *destroyed_ = true; |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Destructor) |
michael@0 | 49 | |
michael@0 | 50 | private: |
michael@0 | 51 | bool *destroyed_; |
michael@0 | 52 | }; |
michael@0 | 53 | |
michael@0 | 54 | class TargetClass { |
michael@0 | 55 | public: |
michael@0 | 56 | TargetClass(int *ran) : ran_(ran) {} |
michael@0 | 57 | |
michael@0 | 58 | void m1(int x) { |
michael@0 | 59 | std::cerr << __FUNCTION__ << " " << x << std::endl; |
michael@0 | 60 | *ran_ = 1; |
michael@0 | 61 | } |
michael@0 | 62 | |
michael@0 | 63 | void m2(int x, int y) { |
michael@0 | 64 | std::cerr << __FUNCTION__ << " " << x << " " << y << std::endl; |
michael@0 | 65 | *ran_ = 2; |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | void m1set(bool *z) { |
michael@0 | 69 | std::cerr << __FUNCTION__ << std::endl; |
michael@0 | 70 | *z = true; |
michael@0 | 71 | } |
michael@0 | 72 | int return_int(int x) { |
michael@0 | 73 | std::cerr << __FUNCTION__ << std::endl; |
michael@0 | 74 | return x; |
michael@0 | 75 | } |
michael@0 | 76 | void destructor_target(Destructor*) { |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | void destructor_target_ref(RefPtr<Destructor> destructor) { |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | int *ran_; |
michael@0 | 83 | }; |
michael@0 | 84 | |
michael@0 | 85 | |
michael@0 | 86 | class RunnableArgsTest : public ::testing::Test { |
michael@0 | 87 | public: |
michael@0 | 88 | RunnableArgsTest() : ran_(0), cl_(&ran_){} |
michael@0 | 89 | |
michael@0 | 90 | void Test1Arg() { |
michael@0 | 91 | nsRunnable * r = WrapRunnable(&cl_, &TargetClass::m1, 1); |
michael@0 | 92 | r->Run(); |
michael@0 | 93 | ASSERT_EQ(1, ran_); |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | void Test2Args() { |
michael@0 | 97 | nsRunnable* r = WrapRunnable(&cl_, &TargetClass::m2, 1, 2); |
michael@0 | 98 | r->Run(); |
michael@0 | 99 | ASSERT_EQ(2, ran_); |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | private: |
michael@0 | 103 | int ran_; |
michael@0 | 104 | TargetClass cl_; |
michael@0 | 105 | }; |
michael@0 | 106 | |
michael@0 | 107 | class DispatchTest : public ::testing::Test { |
michael@0 | 108 | public: |
michael@0 | 109 | DispatchTest() : ran_(0), cl_(&ran_) {} |
michael@0 | 110 | |
michael@0 | 111 | void SetUp() { |
michael@0 | 112 | nsresult rv; |
michael@0 | 113 | target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); |
michael@0 | 114 | ASSERT_TRUE(NS_SUCCEEDED(rv)); |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | void Test1Arg() { |
michael@0 | 118 | nsRunnable* r = WrapRunnable(&cl_, &TargetClass::m1, 1); |
michael@0 | 119 | target_->Dispatch(r, NS_DISPATCH_SYNC); |
michael@0 | 120 | ASSERT_EQ(1, ran_); |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | void Test2Args() { |
michael@0 | 124 | nsRunnable* r = WrapRunnable(&cl_, &TargetClass::m2, 1, 2); |
michael@0 | 125 | target_->Dispatch(r, NS_DISPATCH_SYNC); |
michael@0 | 126 | ASSERT_EQ(2, ran_); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | void Test1Set() { |
michael@0 | 130 | bool x = false; |
michael@0 | 131 | target_->Dispatch(WrapRunnable(&cl_, &TargetClass::m1set, &x), |
michael@0 | 132 | NS_DISPATCH_SYNC); |
michael@0 | 133 | ASSERT_TRUE(x); |
michael@0 | 134 | } |
michael@0 | 135 | |
michael@0 | 136 | void TestRet() { |
michael@0 | 137 | int z; |
michael@0 | 138 | int x = 10; |
michael@0 | 139 | |
michael@0 | 140 | target_->Dispatch(WrapRunnableRet(&cl_, &TargetClass::return_int, x, &z), |
michael@0 | 141 | NS_DISPATCH_SYNC); |
michael@0 | 142 | ASSERT_EQ(10, z); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | protected: |
michael@0 | 146 | int ran_; |
michael@0 | 147 | TargetClass cl_; |
michael@0 | 148 | nsCOMPtr<nsIEventTarget> target_; |
michael@0 | 149 | }; |
michael@0 | 150 | |
michael@0 | 151 | |
michael@0 | 152 | TEST_F(RunnableArgsTest, OneArgument) { |
michael@0 | 153 | Test1Arg(); |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | TEST_F(RunnableArgsTest, TwoArguments) { |
michael@0 | 157 | Test2Args(); |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | TEST_F(DispatchTest, OneArgument) { |
michael@0 | 161 | Test1Arg(); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | TEST_F(DispatchTest, TwoArguments) { |
michael@0 | 165 | Test2Args(); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | TEST_F(DispatchTest, Test1Set) { |
michael@0 | 169 | Test1Set(); |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | TEST_F(DispatchTest, TestRet) { |
michael@0 | 173 | TestRet(); |
michael@0 | 174 | } |
michael@0 | 175 | |
michael@0 | 176 | void SetNonMethod(TargetClass *cl, int x) { |
michael@0 | 177 | cl->m1(x); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | int SetNonMethodRet(TargetClass *cl, int x) { |
michael@0 | 181 | cl->m1(x); |
michael@0 | 182 | |
michael@0 | 183 | return x; |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | TEST_F(DispatchTest, TestNonMethod) { |
michael@0 | 187 | test_utils->sts_target()->Dispatch( |
michael@0 | 188 | WrapRunnableNM(SetNonMethod, &cl_, 10), NS_DISPATCH_SYNC); |
michael@0 | 189 | |
michael@0 | 190 | ASSERT_EQ(1, ran_); |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | TEST_F(DispatchTest, TestNonMethodRet) { |
michael@0 | 194 | int z; |
michael@0 | 195 | |
michael@0 | 196 | test_utils->sts_target()->Dispatch( |
michael@0 | 197 | WrapRunnableNMRet(SetNonMethodRet, &cl_, 10, &z), NS_DISPATCH_SYNC); |
michael@0 | 198 | |
michael@0 | 199 | ASSERT_EQ(1, ran_); |
michael@0 | 200 | ASSERT_EQ(10, z); |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | TEST_F(DispatchTest, TestDestructor) { |
michael@0 | 204 | bool destroyed = false; |
michael@0 | 205 | RefPtr<Destructor> destructor = new Destructor(&destroyed); |
michael@0 | 206 | target_->Dispatch(WrapRunnable(&cl_, &TargetClass::destructor_target, |
michael@0 | 207 | destructor), |
michael@0 | 208 | NS_DISPATCH_SYNC); |
michael@0 | 209 | ASSERT_FALSE(destroyed); |
michael@0 | 210 | destructor = nullptr; |
michael@0 | 211 | ASSERT_TRUE(destroyed); |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | TEST_F(DispatchTest, TestDestructorRef) { |
michael@0 | 215 | bool destroyed = false; |
michael@0 | 216 | RefPtr<Destructor> destructor = new Destructor(&destroyed); |
michael@0 | 217 | target_->Dispatch(WrapRunnable(&cl_, &TargetClass::destructor_target_ref, |
michael@0 | 218 | destructor), |
michael@0 | 219 | NS_DISPATCH_SYNC); |
michael@0 | 220 | ASSERT_FALSE(destroyed); |
michael@0 | 221 | destructor = nullptr; |
michael@0 | 222 | ASSERT_TRUE(destroyed); |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | |
michael@0 | 226 | } // end of namespace |
michael@0 | 227 | |
michael@0 | 228 | |
michael@0 | 229 | int main(int argc, char **argv) { |
michael@0 | 230 | test_utils = new MtransportTestUtils(); |
michael@0 | 231 | |
michael@0 | 232 | // Start the tests |
michael@0 | 233 | ::testing::InitGoogleTest(&argc, argv); |
michael@0 | 234 | |
michael@0 | 235 | int rv = RUN_ALL_TESTS(); |
michael@0 | 236 | delete test_utils; |
michael@0 | 237 | return rv; |
michael@0 | 238 | } |
michael@0 | 239 |