1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "client/mdns_utils.h"
18 
19 #include <gtest/gtest.h>
20 
21 namespace mdns {
22 
23 TEST(mdns_utils, mdns_parse_instance_name) {
24     // Just the instance name
25     {
26         std::string str = ".";
27         auto res = mdns_parse_instance_name(str);
28         ASSERT_TRUE(res.has_value());
29         EXPECT_EQ(str, res->instance_name);
30         EXPECT_TRUE(res->service_name.empty());
31         EXPECT_TRUE(res->transport_type.empty());
32     }
33     {
34         std::string str = "my.name";
35         auto res = mdns_parse_instance_name(str);
36         ASSERT_TRUE(res.has_value());
37         EXPECT_EQ(str, res->instance_name);
38         EXPECT_TRUE(res->service_name.empty());
39         EXPECT_TRUE(res->transport_type.empty());
40     }
41     {
42         std::string str = "my.name.";
43         auto res = mdns_parse_instance_name(str);
44         ASSERT_TRUE(res.has_value());
45         EXPECT_EQ(str, res->instance_name);
46         EXPECT_TRUE(res->service_name.empty());
47         EXPECT_TRUE(res->transport_type.empty());
48     }
49 
50     // With "_tcp", "_udp" transport type
51     for (const std::string_view transport : {"._tcp", "._udp"}) {
52         {
53             std::string str = android::base::StringPrintf("%s", transport.data());
54             auto res = mdns_parse_instance_name(str);
55             EXPECT_FALSE(res.has_value());
56         }
57         {
58             std::string str = android::base::StringPrintf("%s.", transport.data());
59             auto res = mdns_parse_instance_name(str);
60             EXPECT_FALSE(res.has_value());
61         }
62         {
63             std::string str = android::base::StringPrintf("service%s", transport.data());
64             auto res = mdns_parse_instance_name(str);
65             EXPECT_FALSE(res.has_value());
66         }
67         {
68             std::string str = android::base::StringPrintf(".service%s", transport.data());
69             auto res = mdns_parse_instance_name(str);
70             EXPECT_FALSE(res.has_value());
71         }
72         {
73             std::string str = android::base::StringPrintf("service.%s", transport.data());
74             auto res = mdns_parse_instance_name(str);
75             EXPECT_FALSE(res.has_value());
76         }
77         {
78             std::string str = android::base::StringPrintf("my.service%s", transport.data());
79             auto res = mdns_parse_instance_name(str);
80             ASSERT_TRUE(res.has_value());
81             EXPECT_EQ(res->instance_name, "my");
82             EXPECT_EQ(res->service_name, "service");
83             EXPECT_EQ(res->transport_type, transport.substr(1));
84         }
85         {
86             std::string str = android::base::StringPrintf("my.service%s.", transport.data());
87             auto res = mdns_parse_instance_name(str);
88             ASSERT_TRUE(res.has_value());
89             EXPECT_EQ(res->instance_name, "my");
90             EXPECT_EQ(res->service_name, "service");
91             EXPECT_EQ(res->transport_type, transport.substr(1));
92         }
93         {
94             std::string str = android::base::StringPrintf("my..service%s", transport.data());
95             auto res = mdns_parse_instance_name(str);
96             ASSERT_TRUE(res.has_value());
97             EXPECT_EQ(res->instance_name, "my.");
98             EXPECT_EQ(res->service_name, "service");
99             EXPECT_EQ(res->transport_type, transport.substr(1));
100         }
101         {
102             std::string str = android::base::StringPrintf("my.name.service%s.", transport.data());
103             auto res = mdns_parse_instance_name(str);
104             ASSERT_TRUE(res.has_value());
105             EXPECT_EQ(res->instance_name, "my.name");
106             EXPECT_EQ(res->service_name, "service");
107             EXPECT_EQ(res->transport_type, transport.substr(1));
108         }
109         {
110             std::string str = android::base::StringPrintf("name.service.%s.", transport.data());
111             auto res = mdns_parse_instance_name(str);
112             EXPECT_FALSE(res.has_value());
113         }
114 
115         // With ".local" domain
116         {
117             std::string str = ".local";
118             auto res = mdns_parse_instance_name(str);
119             EXPECT_FALSE(res.has_value());
120         }
121         {
122             std::string str = ".local.";
123             auto res = mdns_parse_instance_name(str);
124             EXPECT_FALSE(res.has_value());
125         }
126         {
127             std::string str = "name.local";
128             auto res = mdns_parse_instance_name(str);
129             EXPECT_FALSE(res.has_value());
130         }
131         {
132             std::string str = android::base::StringPrintf("%s.local", transport.data());
133             auto res = mdns_parse_instance_name(str);
134             EXPECT_FALSE(res.has_value());
135         }
136         {
137             std::string str = android::base::StringPrintf("service%s.local", transport.data());
138             auto res = mdns_parse_instance_name(str);
139             EXPECT_FALSE(res.has_value());
140         }
141         {
142             std::string str = android::base::StringPrintf("name.service%s.local", transport.data());
143             auto res = mdns_parse_instance_name(str);
144             ASSERT_TRUE(res.has_value());
145             EXPECT_EQ(res->instance_name, "name");
146             EXPECT_EQ(res->service_name, "service");
147             EXPECT_EQ(res->transport_type, transport.substr(1));
148         }
149         {
150             std::string str =
151                     android::base::StringPrintf("name.service%s.local.", transport.data());
152             auto res = mdns_parse_instance_name(str);
153             ASSERT_TRUE(res.has_value());
154             EXPECT_EQ(res->instance_name, "name");
155             EXPECT_EQ(res->service_name, "service");
156             EXPECT_EQ(res->transport_type, transport.substr(1));
157         }
158         {
159             std::string str =
160                     android::base::StringPrintf("name.service%s..local.", transport.data());
161             auto res = mdns_parse_instance_name(str);
162             EXPECT_FALSE(res.has_value());
163         }
164         {
165             std::string str =
166                     android::base::StringPrintf("name.service.%s.local.", transport.data());
167             auto res = mdns_parse_instance_name(str);
168             EXPECT_FALSE(res.has_value());
169         }
170     }
171 }
172 
173 }  // namespace mdns
174