Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: remoting/protocol/jingle_messages_unittest.cc

Issue 2567953002: [Chromoting] Plugin message in JingleMessage (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/protocol/jingle_messages.h" 5 #include "remoting/protocol/jingle_messages.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/strings/string_util.h"
11 #include "remoting/protocol/content_description.h" 12 #include "remoting/protocol/content_description.h"
12 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 15 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
15 #include "third_party/webrtc/libjingle/xmpp/constants.h" 16 #include "third_party/webrtc/libjingle/xmpp/constants.h"
16 17
17 using buzz::QName; 18 using buzz::QName;
18 using buzz::XmlAttr; 19 using buzz::XmlAttr;
19 using buzz::XmlElement; 20 using buzz::XmlElement;
20 21
21 namespace remoting { 22 namespace remoting {
22 namespace protocol { 23 namespace protocol {
23 24
24 namespace { 25 namespace {
25 26
26 const char kXmlNsNs[] = "http://www.w3.org/2000/xmlns/"; 27 const char kXmlNsNs[] = "http://www.w3.org/2000/xmlns/";
27 const char kXmlNs[] = "xmlns"; 28 const char kXmlNs[] = "xmlns";
28 29
30 bool VerifyXml(const XmlElement* exp,
31 const XmlElement* val,
32 std::string* error);
33
34 bool VerifyXmlChildrenUnordered(const XmlElement* exp,
35 const XmlElement* val,
36 bool exp_is_expected,
37 std::string* error) {
38 const XmlElement* exp_child = exp->FirstElement();
39 while (exp_child) {
40 const XmlElement* val_child = val->FirstElement();
41 while (val_child) {
42 if (VerifyXml(exp_child, val_child, error)) {
43 break;
44 }
45 val_child = val_child->NextElement();
46 }
47 if (!val_child) {
48 if (error->empty()) {
49 if (exp_is_expected) {
50 *error = "<" + exp_child->Name().Merged() + "> is expected, "
51 "but not found";
52 } else {
53 *error = "Unexpected <" + exp_child->Name().Merged() + "> found";
54 }
55 }
56 return false;
57 }
58 exp_child = exp_child->NextElement();
59 }
60 return true;
61 }
62
29 // Compares two XML blobs and returns true if they are 63 // Compares two XML blobs and returns true if they are
30 // equivalent. Otherwise |error| is set to error message that 64 // equivalent. Otherwise |error| is set to error message that
31 // specifies the first test. 65 // specifies the first test.
32 bool VerifyXml(const XmlElement* exp, 66 bool VerifyXml(const XmlElement* exp,
Sergey Ulanov 2016/12/14 01:31:50 There are some messages for which order matters. P
Hzj_jie 2016/12/14 20:03:48 Got you. Then I would prefer to remove the unorder
33 const XmlElement* val, 67 const XmlElement* val,
34 std::string* error) { 68 std::string* error) {
35 if (exp->Name() != val->Name()) { 69 if (exp->Name() != val->Name()) {
36 *error = "<" + exp->Name().Merged() + ">" + " is expected, but " + 70 *error = "<" + exp->Name().Merged() + ">" + " is expected, but " +
37 "<" + val->Name().Merged() + ">" + " found"; 71 "<" + val->Name().Merged() + ">" + " found";
38 return false; 72 return false;
39 } 73 }
40 if (exp->BodyText() != val->BodyText()) { 74 if (exp->BodyText() != val->BodyText()) {
41 *error = "<" + exp->Name().LocalPart() + ">" + exp->BodyText() + 75 *error = "<" + exp->Name().LocalPart() + ">" + exp->BodyText() +
42 "</" + exp->Name().LocalPart() + ">" " is expected, but found " + 76 "</" + exp->Name().LocalPart() + ">" " is expected, but found " +
(...skipping 22 matching lines...) Expand all
65 val_attr->Name() == QName(kXmlNs)) { 99 val_attr->Name() == QName(kXmlNs)) {
66 continue; // Skip NS attributes. 100 continue; // Skip NS attributes.
67 } 101 }
68 if (exp->Attr(val_attr->Name()) != val_attr->Value()) { 102 if (exp->Attr(val_attr->Name()) != val_attr->Value()) {
69 *error = "In <" + exp->Name().LocalPart() + "> unexpected attribute " + 103 *error = "In <" + exp->Name().LocalPart() + "> unexpected attribute " +
70 val_attr->Name().LocalPart(); 104 val_attr->Name().LocalPart();
71 return false; 105 return false;
72 } 106 }
73 } 107 }
74 108
75 const XmlElement* exp_child = exp->FirstElement(); 109 if (!VerifyXmlChildrenUnordered(exp, val, true, error) ||
76 const XmlElement* val_child = val->FirstElement(); 110 !VerifyXmlChildrenUnordered(val, exp, false, error)) {
77 while (exp_child && val_child) {
78 if (!VerifyXml(exp_child, val_child, error))
79 return false;
80 exp_child = exp_child->NextElement();
81 val_child = val_child->NextElement();
82 }
83 if (exp_child) {
84 *error = "<" + exp_child->Name().Merged() + "> is expected, but not found";
85 return false; 111 return false;
86 } 112 }
87 113
88 if (val_child) {
89 *error = "Unexpected <" + val_child->Name().Merged() + "> found";
90 return false;
91 }
92
93 return true; 114 return true;
94 } 115 }
95 116
96 // Parses |message_text| to JingleMessage. 117 // Parses |message_text| to JingleMessage.
97 void ParseJingleMessageFromXml(const char* message_text, 118 void ParseJingleMessageFromXml(const char* message_text,
98 JingleMessage* parsed) { 119 JingleMessage* parsed) {
99 std::unique_ptr<XmlElement> source_message(XmlElement::ForStr(message_text)); 120 std::unique_ptr<XmlElement> source_message(XmlElement::ForStr(message_text));
100 ASSERT_TRUE(source_message.get()); 121 ASSERT_TRUE(source_message.get());
101 122
102 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get())); 123 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
103 124
104 std::string error; 125 std::string error;
105 EXPECT_TRUE(parsed->ParseXml(source_message.get(), &error)) << error; 126 EXPECT_TRUE(parsed->ParseXml(source_message.get(), &error)) << error;
106 } 127 }
107 128
108 129
109 // Parses |message_text| to JingleMessage then attempts to format it to XML and 130 // Parses |message_text| to JingleMessage then attempts to format it to XML and
110 // verifies that the same XML content is generated. 131 // verifies that the same XML content is generated.
111 void ParseFormatAndCompare(const char* message_text, JingleMessage* parsed) { 132 void ParseFormatAndCompare(const char* message_text, JingleMessage* parsed) {
112 std::unique_ptr<XmlElement> source_message(XmlElement::ForStr(message_text)); 133 std::unique_ptr<XmlElement> source_message(XmlElement::ForStr(message_text));
113 ASSERT_TRUE(source_message.get()); 134 ASSERT_TRUE(source_message.get());
114 135
115 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get())); 136 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
116 137
117 std::string error; 138 std::string error;
118 EXPECT_TRUE(parsed->ParseXml(source_message.get(), &error)) << error; 139 EXPECT_TRUE(parsed->ParseXml(source_message.get(), &error)) << error;
119 140
120 std::unique_ptr<XmlElement> formatted_message(parsed->ToXml()); 141 std::unique_ptr<XmlElement> formatted_message(parsed->ToXml());
121 ASSERT_TRUE(formatted_message.get()); 142 ASSERT_TRUE(formatted_message.get());
143
122 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error)) 144 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
123 << error; 145 << error;
124 } 146 }
125 147
126 } // namespace 148 } // namespace
127 149
128 // Session-initiate message for current ICE-based protocol. 150 // Session-initiate message for current ICE-based protocol.
129 TEST(JingleMessageTest, SessionInitiate) { 151 TEST(JingleMessageTest, SessionInitiate) {
130 const char* kTestSessionInitiateMessage = 152 const char* kTestSessionInitiateMessage =
131 "<iq to='user@gmail.com/chromoting016DBB07' type='set' " 153 "<iq to='user@gmail.com/chromoting016DBB07' type='set' "
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 } else { 615 } else {
594 ParseFormatAndCompare(message_str.c_str(), &message); 616 ParseFormatAndCompare(message_str.c_str(), &message);
595 } 617 }
596 618
597 EXPECT_EQ(message.action, JingleMessage::SESSION_TERMINATE); 619 EXPECT_EQ(message.action, JingleMessage::SESSION_TERMINATE);
598 EXPECT_EQ(message.reason, JingleMessage::DECLINE); 620 EXPECT_EQ(message.reason, JingleMessage::DECLINE);
599 EXPECT_EQ(message.error_code, error); 621 EXPECT_EQ(message.error_code, error);
600 } 622 }
601 } 623 }
602 624
625 namespace {
626
627 void TestPluginMessage(bool insert_before_regular_message) {
Sergey Ulanov 2016/12/12 23:00:03 I doubt it's useful to test for the case when the
Hzj_jie 2016/12/13 00:20:51 I have not found there is a strong sequence requir
Sergey Ulanov 2016/12/14 01:31:50 Yes, both formats are valid. My point was that it'
Hzj_jie 2016/12/14 20:03:48 Updated.
628 const char* kMessageWithPluginTag =
629 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
630 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
631 "xmlns:cli='jabber:client'><jingle action='$1' "
632 "sid='2227053353' xmlns='urn:xmpp:jingle:1'>$2"
633 "<gr:plugin xmlns:gr='google:remoting'>"
634 "<gr:sometag>some-message</gr:sometag>"
635 "</gr:plugin>$3</jingle></cli:iq>";
636 for (int i = JingleMessage::SESSION_INITIATE;
637 i <= JingleMessage::TRANSPORT_INFO; i++) {
638 JingleMessage::ActionType action_type =
639 static_cast<JingleMessage::ActionType>(i);
640 std::vector<std::string> subst = {
Sergey Ulanov 2016/12/12 23:00:03 subst is not a good name
Hzj_jie 2016/12/13 00:20:51 Done.
641 JingleMessage::GetActionName(action_type)
642 };
643 if (insert_before_regular_message) {
644 subst.emplace_back();
645 }
646 if (action_type == JingleMessage::SESSION_INFO) {
647 subst.push_back("<test-info>test-message</test-info>");
648 } else if (action_type == JingleMessage::SESSION_TERMINATE) {
649 subst.emplace_back();
650 } else if (action_type == JingleMessage::TRANSPORT_INFO) {
Sergey Ulanov 2016/12/12 23:00:03 I don't think we want to allow plugins for transpo
Hzj_jie 2016/12/13 00:20:51 I thought this before, but it would make JingleMes
Sergey Ulanov 2016/12/14 01:31:50 It would make JingleMessage very slightly more com
Hzj_jie 2016/12/14 20:03:48 I think it can make both JingleMessage and JingleS
Sergey Ulanov 2016/12/15 19:18:25 I think complexity comes not only from amount of c
Hzj_jie 2016/12/15 22:41:19 IMO how to handle the message is not part of the f
651 subst.push_back(
652 "<content name='chromoting' creator='initiator'>"
653 "<transport xmlns='google:remoting:webrtc'>"
654 "<credentials channel='event' ufrag='tPUyEAmQrEw3y7hi' "
655 "password='2iRdhLfawKZC5ydJ'/>"
656 "<credentials channel='video' ufrag='EPK3CXo5sTLJSez0' "
657 "password='eM0VUfUkZ+1Pyi0M'/>"
658 "<candidate name='event' foundation='725747215' "
659 "address='172.23.164.186' port='59089' type='local' "
660 "protocol='udp' priority='2122194688' generation='0'/>"
661 "<candidate name='video' foundation='3623806809' "
662 "address='172.23.164.186' port='57040' type='local' "
663 "protocol='udp' priority='2122194688' generation='0'/>"
664 "</transport>"
665 "</content>");
666 } else {
667 subst.push_back("<content name='chromoting' creator='initiator'>"
668 "<description xmlns='google:remoting'>"
669 "<authentication><auth-token>"
670 "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
671 "</auth-token></authentication>"
672 "</description>"
673 "<transport xmlns='google:remoting:webrtc' />"
674 "</content>");
675 }
676 if (!insert_before_regular_message) {
677 subst.emplace_back();
678 }
679 std::string message_str = base::ReplaceStringPlaceholders(
680 kMessageWithPluginTag, subst, nullptr);
681
682 JingleMessage message;
683 ParseFormatAndCompare(message_str.c_str(), &message);
684
685 EXPECT_TRUE(message.plugin_message);
686 XmlElement expected(QName("google:remoting", "plugin"));
687 expected.AddElement(new XmlElement(QName("google:remoting", "sometag")));
688 expected.FirstElement()->SetBodyText("some-message");
689 std::string error;
690 EXPECT_TRUE(VerifyXml(&expected, message.plugin_message.get(), &error))
691 << error;
692 }
693 }
694
695 } // namespace
696
697 TEST(JingleMessageTest, PluginMessage) {
698 TestPluginMessage(false);
699 TestPluginMessage(true);
700 }
701
603 } // namespace protocol 702 } // namespace protocol
604 } // namespace remoting 703 } // namespace remoting
OLDNEW
« remoting/protocol/jingle_messages.h ('K') | « remoting/protocol/jingle_messages.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698