Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 1 | // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include <memory> |
| 6 | |
| 7 | #include "base/bind.h" |
| 8 | #include "base/callback_helpers.h" |
| 9 | #include "base/json/json_reader.h" |
| 10 | #include "base/macros.h" |
| 11 | #include "base/values.h" |
| 12 | #include "chrome/test/base/in_process_browser_test.h" |
| 13 | #include "chrome/test/base/test_service_manager_listener.h" |
| 14 | #include "content/public/common/service_manager_connection.h" |
| 15 | #include "content/public/test/test_utils.h" |
| 16 | #include "services/data_decoder/public/cpp/safe_xml_parser.h" |
Ken Rockot | 19db638 | 2018-02-10 01:41:02 | [diff] [blame^] | 17 | #include "services/data_decoder/public/mojom/constants.mojom.h" |
| 18 | #include "services/data_decoder/public/mojom/xml_parser.mojom.h" |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 19 | #include "services/service_manager/public/cpp/connector.h" |
| 20 | |
| 21 | namespace { |
| 22 | |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 23 | constexpr char kTestXml[] = "<hello>bonjour</hello>"; |
| 24 | constexpr char kTestJson[] = R"( |
| 25 | {"type": "element", |
| 26 | "tag": "hello", |
| 27 | "children": [{"type": "text", "text": "bonjour"}] |
| 28 | } )"; |
| 29 | |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 30 | class SafeXmlParserTest : public InProcessBrowserTest { |
| 31 | public: |
| 32 | SafeXmlParserTest() = default; |
| 33 | ~SafeXmlParserTest() override = default; |
| 34 | |
| 35 | protected: |
| 36 | void SetUpOnMainThread() override { |
| 37 | InProcessBrowserTest::SetUpOnMainThread(); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 38 | listener_.Init(); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | uint32_t GetServiceStartCount(const std::string& service_name) const { |
| 42 | return listener_.GetServiceStartCount(service_name); |
| 43 | } |
| 44 | |
| 45 | // Parses |xml| and compares its parsed representation with |expected_json|. |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 46 | // If a |batch_id| is provided, it is passed to the ParseXml call (to group |
| 47 | // parsing of multiple XML documents in the same utility process). |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 48 | // If |expected_json| is empty, the XML parsing is expected to fail. |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 49 | void TestParse(base::StringPiece xml, |
| 50 | const std::string& expected_json, |
| 51 | const std::string& batch_id = std::string()) { |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 52 | SCOPED_TRACE(xml); |
| 53 | |
| 54 | base::RunLoop run_loop; |
| 55 | std::unique_ptr<base::Value> expected_value; |
| 56 | if (!expected_json.empty()) { |
| 57 | expected_value = base::JSONReader::Read(expected_json); |
| 58 | DCHECK(expected_value) << "Bad test, incorrect JSON: " << expected_json; |
| 59 | } |
| 60 | |
| 61 | data_decoder::ParseXml( |
| 62 | content::ServiceManagerConnection::GetForProcess()->GetConnector(), |
| 63 | xml.as_string(), |
| 64 | base::BindOnce(&SafeXmlParserTest::XmlParsingDone, |
| 65 | base::Unretained(this), run_loop.QuitClosure(), |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 66 | std::move(expected_value)), |
| 67 | batch_id); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 68 | run_loop.Run(); |
| 69 | } |
| 70 | |
| 71 | private: |
| 72 | void XmlParsingDone(base::Closure quit_loop_closure, |
| 73 | std::unique_ptr<base::Value> expected_value, |
| 74 | std::unique_ptr<base::Value> actual_value, |
| 75 | const base::Optional<std::string>& error) { |
| 76 | base::ScopedClosureRunner(std::move(quit_loop_closure)); |
| 77 | if (!expected_value) { |
| 78 | EXPECT_FALSE(actual_value); |
| 79 | EXPECT_TRUE(error); |
| 80 | return; |
| 81 | } |
| 82 | EXPECT_FALSE(error); |
| 83 | ASSERT_TRUE(actual_value); |
| 84 | EXPECT_EQ(*expected_value, *actual_value); |
| 85 | } |
| 86 | |
| 87 | data_decoder::mojom::XmlParserPtr xml_parser_ptr_; |
| 88 | TestServiceManagerListener listener_; |
| 89 | |
| 90 | DISALLOW_COPY_AND_ASSIGN(SafeXmlParserTest); |
| 91 | }; |
| 92 | |
| 93 | } // namespace |
| 94 | |
| 95 | // Tests that SafeXmlParser does parse. (actual XML parsing is tested in the |
| 96 | // service unit-tests). |
| 97 | IN_PROC_BROWSER_TEST_F(SafeXmlParserTest, Parse) { |
| 98 | TestParse("[\"this is JSON not XML\"]", ""); |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 99 | TestParse(kTestXml, kTestJson); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 100 | } |
| 101 | |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 102 | // Tests that a new service is created for each SafeXmlParser::Parse() call. |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 103 | IN_PROC_BROWSER_TEST_F(SafeXmlParserTest, Isolation) { |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 104 | constexpr size_t kParseCount = 5; |
| 105 | for (size_t i = 0; i < kParseCount; i++) |
| 106 | TestParse(kTestXml, kTestJson); |
| 107 | EXPECT_EQ(kParseCount, |
| 108 | GetServiceStartCount(data_decoder::mojom::kServiceName)); |
| 109 | } |
| 110 | |
| 111 | // Tests that using a batch ID allows service reuse. |
| 112 | IN_PROC_BROWSER_TEST_F(SafeXmlParserTest, IsolationWithBatchId) { |
| 113 | constexpr char kBatchId1[] = "batch1"; |
| 114 | constexpr char kBatchId2[] = "batch2"; |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 115 | for (int i = 0; i < 5; i++) { |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 116 | TestParse(kTestXml, kTestJson, kBatchId1); |
| 117 | TestParse(kTestXml, kTestJson, kBatchId2); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 118 | } |
Jay Civelli | ed29765 | 2017-11-29 04:17:46 | [diff] [blame] | 119 | EXPECT_EQ(2U, GetServiceStartCount(data_decoder::mojom::kServiceName)); |
Jay Civelli | 90a4cb1 | 2017-11-28 21:04:52 | [diff] [blame] | 120 | } |