summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp')
-rw-r--r--dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp b/dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp
new file mode 100644
index 0000000000..1b54126dd6
--- /dev/null
+++ b/dom/media/webrtc/transport/test/proxy_tunnel_socket_unittest.cpp
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Original authors: ekr@rtfm.com; ryan@tokbox.com
+
+#include <vector>
+#include <numeric>
+
+#include "nr_socket_tcp.h"
+#include "WebrtcTCPSocketWrapper.h"
+
+#define GTEST_HAS_RTTI 0
+#include "gtest/gtest.h"
+#include "gtest_utils.h"
+
+using namespace mozilla;
+
+// update TestReadMultipleSizes if you change this
+const std::string kHelloMessage = "HELLO IS IT ME YOU'RE LOOKING FOR?";
+
+class NrTcpSocketTest : public MtransportTest {
+ public:
+ NrTcpSocketTest()
+ : mSProxy(nullptr),
+ nr_socket_(nullptr),
+ mEmptyArray(0),
+ mReadChunkSize(0),
+ mReadChunkSizeIncrement(1),
+ mReadAllowance(-1),
+ mConnected(false) {}
+
+ void SetUp() override {
+ mSProxy = new NrTcpSocket(nullptr);
+ int r = nr_socket_create_int((void*)mSProxy.get(), mSProxy->vtbl(),
+ &nr_socket_);
+ ASSERT_EQ(0, r);
+
+ // fake calling AsyncOpen() due to IPC calls. must be non-null
+ mSProxy->AssignChannel_DoNotUse(new WebrtcTCPSocketWrapper(nullptr));
+ }
+
+ void TearDown() override { mSProxy->close(); }
+
+ static void readable_cb(NR_SOCKET s, int how, void* cb_arg) {
+ NrTcpSocketTest* test = (NrTcpSocketTest*)cb_arg;
+ size_t capacity = std::min(test->mReadChunkSize, test->mReadAllowance);
+ nsTArray<uint8_t> array(capacity);
+ size_t read;
+
+ nr_socket_read(test->nr_socket_, (char*)array.Elements(), array.Capacity(),
+ &read, 0);
+
+ ASSERT_TRUE(read <= array.Capacity());
+ ASSERT_TRUE(test->mReadAllowance >= read);
+
+ array.SetLength(read);
+ test->mData.AppendElements(array);
+ test->mReadAllowance -= read;
+
+ // We may read more bytes each time we're called. This way we can ensure we
+ // consume buffers partially and across multiple buffers.
+ test->mReadChunkSize += test->mReadChunkSizeIncrement;
+
+ if (test->mReadAllowance > 0) {
+ NR_ASYNC_WAIT(s, how, &NrTcpSocketTest::readable_cb, cb_arg);
+ }
+ }
+
+ static void writable_cb(NR_SOCKET s, int how, void* cb_arg) {
+ NrTcpSocketTest* test = (NrTcpSocketTest*)cb_arg;
+ test->mConnected = true;
+ }
+
+ const std::string DataString() {
+ return std::string((char*)mData.Elements(), mData.Length());
+ }
+
+ protected:
+ RefPtr<NrTcpSocket> mSProxy;
+ nr_socket* nr_socket_;
+
+ nsTArray<uint8_t> mData;
+ nsTArray<uint8_t> mEmptyArray;
+
+ uint32_t mReadChunkSize;
+ uint32_t mReadChunkSizeIncrement;
+ uint32_t mReadAllowance;
+
+ bool mConnected;
+};
+
+TEST_F(NrTcpSocketTest, TestCreate) {}
+
+TEST_F(NrTcpSocketTest, TestConnected) {
+ ASSERT_TRUE(!mConnected);
+
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_WRITE, &NrTcpSocketTest::writable_cb,
+ this);
+
+ // still not connected just registered for writes...
+ ASSERT_TRUE(!mConnected);
+
+ mSProxy->OnConnected("http"_ns);
+
+ ASSERT_TRUE(mConnected);
+}
+
+TEST_F(NrTcpSocketTest, TestRead) {
+ nsTArray<uint8_t> array;
+ array.AppendElements(kHelloMessage.c_str(), kHelloMessage.length());
+
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_READ, &NrTcpSocketTest::readable_cb,
+ this);
+ // this will read 0 bytes here
+ mSProxy->OnRead(std::move(array));
+
+ ASSERT_EQ(kHelloMessage.length(), mSProxy->CountUnreadBytes());
+
+ // callback is still set but terminated due to 0 byte read
+ // start callbacks again (first read is 0 then 1,2,3,...)
+ mSProxy->OnRead(std::move(mEmptyArray));
+
+ ASSERT_EQ(kHelloMessage.length(), mData.Length());
+ ASSERT_EQ(kHelloMessage, DataString());
+}
+
+TEST_F(NrTcpSocketTest, TestReadConstantConsumeSize) {
+ std::string data;
+
+ // triangle number
+ const int kCount = 32;
+
+ // ~17kb
+ // triangle number formula n*(n+1)/2
+ for (int i = 0; i < kCount * (kCount + 1) / 2; ++i) {
+ data += kHelloMessage;
+ }
+
+ // decreasing buffer sizes
+ for (int i = 0, start = 0; i < kCount; ++i) {
+ int length = (kCount - i) * kHelloMessage.length();
+
+ nsTArray<uint8_t> array;
+ array.AppendElements(data.c_str() + start, length);
+ start += length;
+
+ mSProxy->OnRead(std::move(array));
+ }
+
+ ASSERT_EQ(data.length(), mSProxy->CountUnreadBytes());
+
+ // read same amount each callback
+ mReadChunkSize = 128;
+ mReadChunkSizeIncrement = 0;
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_READ, &NrTcpSocketTest::readable_cb,
+ this);
+
+ ASSERT_EQ(data.length(), mSProxy->CountUnreadBytes());
+
+ // start callbacks
+ mSProxy->OnRead(std::move(mEmptyArray));
+
+ ASSERT_EQ(data.length(), mData.Length());
+ ASSERT_EQ(data, DataString());
+}
+
+TEST_F(NrTcpSocketTest, TestReadNone) {
+ char buf[4096];
+ size_t read = 0;
+ int r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
+
+ ASSERT_EQ(R_WOULDBLOCK, r);
+
+ nsTArray<uint8_t> array;
+ array.AppendElements(kHelloMessage.c_str(), kHelloMessage.length());
+ mSProxy->OnRead(std::move(array));
+
+ ASSERT_EQ(kHelloMessage.length(), mSProxy->CountUnreadBytes());
+
+ r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
+
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(kHelloMessage.length(), read);
+ ASSERT_EQ(kHelloMessage, std::string(buf, read));
+}
+
+TEST_F(NrTcpSocketTest, TestReadMultipleSizes) {
+ using namespace std;
+
+ string data;
+ // 515 * kHelloMessage.length() == 17510
+ const size_t kCount = 515;
+ // randomly generated numbers, sums to 17510, 20 numbers
+ vector<int> varyingSizes = {404, 622, 1463, 1597, 1676, 389, 389,
+ 1272, 781, 81, 1030, 1450, 256, 812,
+ 1571, 29, 1045, 911, 643, 1089};
+
+ // changing varyingSizes or the test message breaks this so check here
+ ASSERT_EQ(kCount, 17510 / kHelloMessage.length());
+ ASSERT_EQ(17510, accumulate(varyingSizes.begin(), varyingSizes.end(), 0));
+
+ // ~17kb
+ for (size_t i = 0; i < kCount; ++i) {
+ data += kHelloMessage;
+ }
+
+ nsTArray<uint8_t> array;
+ array.AppendElements(data.c_str(), data.length());
+
+ for (int amountToRead : varyingSizes) {
+ nsTArray<uint8_t> buffer;
+ buffer.AppendElements(array.Elements(), amountToRead);
+ array.RemoveElementsAt(0, amountToRead);
+ mSProxy->OnRead(std::move(buffer));
+ }
+
+ ASSERT_EQ(data.length(), mSProxy->CountUnreadBytes());
+
+ // don't need to read 0 on the first read, so start at 1 and keep going
+ mReadChunkSize = 1;
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_READ, &NrTcpSocketTest::readable_cb,
+ this);
+ // start callbacks
+ mSProxy->OnRead(std::move(mEmptyArray));
+
+ ASSERT_EQ(data.length(), mData.Length());
+ ASSERT_EQ(data, DataString());
+}
+
+TEST_F(NrTcpSocketTest, TestReadConsumeReadDrain) {
+ std::string data;
+ // ~26kb total; should be even
+ const int kCount = 512;
+
+ // there's some division by 2 here so check that kCount is even
+ ASSERT_EQ(0, kCount % 2);
+
+ for (int i = 0; i < kCount; ++i) {
+ data += kHelloMessage;
+ nsTArray<uint8_t> array;
+ array.AppendElements(kHelloMessage.c_str(), kHelloMessage.length());
+ mSProxy->OnRead(std::move(array));
+ }
+
+ // read half at first
+ mReadAllowance = kCount / 2 * kHelloMessage.length();
+ // start by reading 1 byte
+ mReadChunkSize = 1;
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_READ, &NrTcpSocketTest::readable_cb,
+ this);
+ mSProxy->OnRead(std::move(mEmptyArray));
+
+ ASSERT_EQ(data.length() / 2, mSProxy->CountUnreadBytes());
+ ASSERT_EQ(data.length() / 2, mData.Length());
+
+ // fill read buffer back up
+ for (int i = 0; i < kCount / 2; ++i) {
+ data += kHelloMessage;
+ nsTArray<uint8_t> array;
+ array.AppendElements(kHelloMessage.c_str(), kHelloMessage.length());
+ mSProxy->OnRead(std::move(array));
+ }
+
+ // remove read limit
+ mReadAllowance = -1;
+ // used entire read allowance so we need to setup a new await
+ NR_ASYNC_WAIT(mSProxy, NR_ASYNC_WAIT_READ, &NrTcpSocketTest::readable_cb,
+ this);
+ // start callbacks
+ mSProxy->OnRead(std::move(mEmptyArray));
+
+ ASSERT_EQ(data.length(), mData.Length());
+ ASSERT_EQ(data, DataString());
+}