Bug 1508310 - Implement Report-to header support - part 2 - Header parser gtest, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 01 Dec 2018 21:26:09 +0100
changeset 508356 b8e709a8076fa6a5dfd68a045993e2650e124bf6
parent 508355 c435d7c0173e6b9bf699d80e370a657bdff248ed
child 508357 bbcbf470d213b8556c770f85a5cf3ffe216b2c13
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1508310
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1508310 - Implement Report-to header support - part 2 - Header parser gtest, r=smaug
dom/reporting/moz.build
dom/reporting/tests/gtest/TestReportToParser.cpp
dom/reporting/tests/gtest/moz.build
--- a/dom/reporting/moz.build
+++ b/dom/reporting/moz.build
@@ -29,8 +29,10 @@ UNIFIED_SOURCES += [
 include('/ipc/chromium/chromium-config.mozbuild')
 
 with Files('**'):
     BUG_COMPONENT = ('DOM', 'Security')
 
 FINAL_LIBRARY = 'xul'
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
+
+TEST_DIRS += [ 'tests/gtest' ]
new file mode 100644
--- /dev/null
+++ b/dom/reporting/tests/gtest/TestReportToParser.cpp
@@ -0,0 +1,379 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+#include "gtest/gtest.h"
+#include "mozilla/dom/ReportingHeader.h"
+#include "nsNetUtil.h"
+#include "nsIURI.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+TEST(ReportToParser, Basic) {
+  nsCOMPtr<nsIURI> uri;
+
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), "https://example.com");
+  ASSERT_EQ(NS_OK, rv);
+
+  bool urlEqual = false;
+
+  // Empty header.
+  UniquePtr<ReportingHeader::Client> client =
+      ReportingHeader::ParseHeader(nullptr, uri, NS_LITERAL_CSTRING(""));
+  ASSERT_TRUE(!client);
+
+  // Empty header.
+  client =
+      ReportingHeader::ParseHeader(nullptr, uri, NS_LITERAL_CSTRING("    "));
+  ASSERT_TRUE(!client);
+
+  // No minimal attributes
+  client = ReportingHeader::ParseHeader(nullptr, uri, NS_LITERAL_CSTRING("{}"));
+  ASSERT_TRUE(!client);
+
+  // Single client
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 42, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("default"));
+  ASSERT_FALSE(client->mGroups[0].mIncludeSubdomains);
+  ASSERT_EQ(42, client->mGroups[0].mTTL);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 clients, same group name.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 43, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 44, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("default"));
+  ASSERT_EQ(43, client->mGroups[0].mTTL);
+
+  // 2 clients, the first one with an invalid group name.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 43, \"group\": 123, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 44, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("default"));
+  ASSERT_EQ(44, client->mGroups[0].mTTL);
+
+  // 2 clients, the first one with an invalid group name.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 43, \"group\": null, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 44, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("default"));
+  ASSERT_EQ(44, client->mGroups[0].mTTL);
+
+  // 2 clients, the first one with an invalid group name.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 43, \"group\": {}, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 44, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("default"));
+  ASSERT_EQ(44, client->mGroups[0].mTTL);
+
+  // Single client: optional params
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 45, \"group\": \"foobar\", \"include_subdomains\": "
+          "true, \"endpoints\": [{\"url\": \"https://example.com\", "
+          "\"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_TRUE(client->mGroups[0].mName.EqualsLiteral("foobar"));
+  ASSERT_TRUE(client->mGroups[0].mIncludeSubdomains);
+  ASSERT_EQ(45, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: missing max_age.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"endpoints\": [{\"url\": \"https://example.com\", \"priority\": "
+          "1, \"weight\": 2}]},"
+          "{\"max_age\": 46, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(46, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid max_age.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": null, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 46, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(46, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid max_age.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": \"foobar\", \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 46, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(46, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid max_age.
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": {}, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]},"
+          "{\"max_age\": 46, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(46, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: missing endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 47},"
+          "{\"max_age\": 48, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(48, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 47, \"endpoints\": null },"
+          "{\"max_age\": 48, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(48, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 47, \"endpoints\": \"abc\" },"
+          "{\"max_age\": 48, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(48, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 47, \"endpoints\": 42 },"
+          "{\"max_age\": 48, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(48, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: invalid endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 47, \"endpoints\": {} },"
+          "{\"max_age\": 48, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(48, client->mGroups[0].mTTL);
+
+  // 2 clients, the first incomplete: empty endpoints
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 49, \"endpoints\": []},"
+          "{\"max_age\": 50, \"endpoints\": [{\"url\": "
+          "\"https://example.com\", \"priority\": 1, \"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ(50, client->mGroups[0].mTTL);
+
+  // 2 endpoints, the first incomplete: missing url
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 51, \"endpoints\": ["
+                         " {\"priority\": 1, \"weight\": 2},"
+                         " {\"url\": \"https://example.com\", \"priority\": 1, "
+                         "\"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid url
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 51, \"endpoints\": ["
+                         " {\"url\": 42, \"priority\": 1, \"weight\": 2},"
+                         " {\"url\": \"https://example.com\", \"priority\": 1, "
+                         "\"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid url
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 51, \"endpoints\": ["
+          " {\"url\": \"something here\", \"priority\": 1, \"weight\": 2},"
+          " {\"url\": \"https://example.com\", \"priority\": 1, \"weight\": "
+          "2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid url
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 51, \"endpoints\": ["
+                         " {\"url\": {}, \"priority\": 1, \"weight\": 2},"
+                         " {\"url\": \"https://example.com\", \"priority\": 1, "
+                         "\"weight\": 2}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: missing priority
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 52, \"endpoints\": ["
+          " {\"url\": \"https://example.com\", \"weight\": 3}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)3, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid priority
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 52, \"endpoints\": ["
+                         " {\"url\": \"https://example.com\", \"priority\": "
+                         "{}, \"weight\": 2},"
+                         " {\"url\": \"https://example.com\", \"priority\": 2, "
+                         "\"weight\": 3}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)3, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid priority
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 52, \"endpoints\": ["
+                         " {\"url\": \"https://example.com\", \"priority\": "
+                         "\"ok\", \"weight\": 2},"
+                         " {\"url\": \"https://example.com\", \"priority\": 2, "
+                         "\"weight\": 3}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)2, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)3, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: missing weight
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING(
+          "{\"max_age\": 52, \"endpoints\": ["
+          " {\"url\": \"https://example.com\", \"priority\": 5}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)5, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints[0].mWeight);
+
+  // 2 endpoints, the first incomplete: invalid weight
+  client = ReportingHeader::ParseHeader(
+      nullptr, uri,
+      NS_LITERAL_CSTRING("{\"max_age\": 52, \"endpoints\": ["
+                         " {\"url\": \"https://example.com\", \"priority\": 4, "
+                         "\"weight\": []},"
+                         " {\"url\": \"https://example.com\", \"priority\": 5, "
+                         "\"weight\": 6}]}"));
+  ASSERT_TRUE(!!client);
+  ASSERT_EQ((uint32_t)1, client->mGroups.Length());
+  ASSERT_EQ((uint32_t)1, client->mGroups[0].mEndpoints.Length());
+  ASSERT_TRUE(NS_SUCCEEDED(client->mGroups[0].mEndpoints[0].mUrl->Equals(
+                  uri, &urlEqual)) &&
+              urlEqual);
+  ASSERT_EQ((uint32_t)5, client->mGroups[0].mEndpoints[0].mPriority);
+  ASSERT_EQ((uint32_t)6, client->mGroups[0].mEndpoints[0].mWeight);
+}
new file mode 100644
--- /dev/null
+++ b/dom/reporting/tests/gtest/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+UNIFIED_SOURCES = [
+    'TestReportToParser.cpp',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul-gtest'