1 /*
2  * Copyright (C) 2015 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 "transport.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include "adb.h"
22 #include "fdevent/fdevent_test.h"
23 
24 struct TransportTest : public FdeventTest {};
25 
26 static void DisconnectFunc(void* arg, atransport*) {
27     int* count = reinterpret_cast<int*>(arg);
28     ++*count;
29 }
30 
31 TEST_F(TransportTest, RunDisconnects) {
32     atransport t;
33     // RunDisconnects() can be called with an empty atransport.
34     t.RunDisconnects();
35 
36     int count = 0;
37     adisconnect disconnect;
38     disconnect.func = DisconnectFunc;
39     disconnect.opaque = &count;
40     t.AddDisconnect(&disconnect);
41     t.RunDisconnects();
42     ASSERT_EQ(1, count);
43 
44     // disconnect should have been removed automatically.
45     t.RunDisconnects();
46     ASSERT_EQ(1, count);
47 
48     count = 0;
49     t.AddDisconnect(&disconnect);
50     t.RemoveDisconnect(&disconnect);
51     t.RunDisconnects();
52     ASSERT_EQ(0, count);
53 }
54 
55 TEST_F(TransportTest, SetFeatures) {
56     atransport t;
57     ASSERT_EQ(0U, t.features().size());
58 
59     t.SetFeatures(FeatureSetToString(FeatureSet{"foo"}));
60     ASSERT_EQ(1U, t.features().size());
61     ASSERT_TRUE(t.has_feature("foo"));
62 
63     t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar"}));
64     ASSERT_EQ(2U, t.features().size());
65     ASSERT_TRUE(t.has_feature("foo"));
66     ASSERT_TRUE(t.has_feature("bar"));
67 
68     t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar", "foo"}));
69     ASSERT_LE(2U, t.features().size());
70     ASSERT_TRUE(t.has_feature("foo"));
71     ASSERT_TRUE(t.has_feature("bar"));
72 
73     t.SetFeatures(FeatureSetToString(FeatureSet{"bar", "baz"}));
74     ASSERT_EQ(2U, t.features().size());
75     ASSERT_FALSE(t.has_feature("foo"));
76     ASSERT_TRUE(t.has_feature("bar"));
77     ASSERT_TRUE(t.has_feature("baz"));
78 
79     t.SetFeatures("");
80     ASSERT_EQ(0U, t.features().size());
81 }
82 
83 TEST_F(TransportTest, parse_banner_no_features) {
84     atransport t;
85 
86     parse_banner("host::", &t);
87 
88     ASSERT_EQ(0U, t.features().size());
89     ASSERT_EQ(kCsHost, t.GetConnectionState());
90 
91     ASSERT_EQ(std::string(), t.product);
92     ASSERT_EQ(std::string(), t.model);
93     ASSERT_EQ(std::string(), t.device);
94 }
95 
96 TEST_F(TransportTest, parse_banner_product_features) {
97     atransport t;
98 
99     const char banner[] =
100         "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;";
101     parse_banner(banner, &t);
102 
103     ASSERT_EQ(kCsHost, t.GetConnectionState());
104 
105     ASSERT_EQ(0U, t.features().size());
106 
107     ASSERT_EQ(std::string("foo"), t.product);
108     ASSERT_EQ(std::string("bar"), t.model);
109     ASSERT_EQ(std::string("baz"), t.device);
110 }
111 
112 TEST_F(TransportTest, parse_banner_features) {
113     atransport t;
114     const char banner[] =
115         "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;"
116         "features=woodly,doodly";
117     parse_banner(banner, &t);
118 
119     ASSERT_EQ(kCsHost, t.GetConnectionState());
120 
121     ASSERT_EQ(2U, t.features().size());
122     ASSERT_TRUE(t.has_feature("woodly"));
123     ASSERT_TRUE(t.has_feature("doodly"));
124 
125     ASSERT_EQ(std::string("foo"), t.product);
126     ASSERT_EQ(std::string("bar"), t.model);
127     ASSERT_EQ(std::string("baz"), t.device);
128 }
129 
130 #if ADB_HOST
131 TEST_F(TransportTest, test_matches_target) {
132     std::string serial = "foo";
133     std::string devpath = "/path/to/bar";
134     std::string product = "test_product";
135     std::string model = "test_model";
136     std::string device = "test_device";
137 
138     atransport t;
139     t.serial = &serial[0];
140     t.devpath = &devpath[0];
141     t.product = &product[0];
142     t.model = &model[0];
143     t.device = &device[0];
144 
145     // These tests should not be affected by the transport type.
146     for (TransportType type : {kTransportAny, kTransportLocal}) {
147         t.type = type;
148 
149         EXPECT_TRUE(t.MatchesTarget(serial));
150         EXPECT_TRUE(t.MatchesTarget(devpath));
151         EXPECT_TRUE(t.MatchesTarget("product:" + product));
152         EXPECT_TRUE(t.MatchesTarget("model:" + model));
153         EXPECT_TRUE(t.MatchesTarget("device:" + device));
154 
155         // Product, model, and device don't match without the prefix.
156         EXPECT_FALSE(t.MatchesTarget(product));
157         EXPECT_FALSE(t.MatchesTarget(model));
158         EXPECT_FALSE(t.MatchesTarget(device));
159     }
160 }
161 
162 TEST_F(TransportTest, test_matches_target_local) {
163     std::string serial = "100.100.100.100:5555";
164 
165     atransport t;
166     t.serial = &serial[0];
167 
168     // Network address matching should only be used for local transports.
169     for (TransportType type : {kTransportAny, kTransportLocal}) {
170         t.type = type;
171         bool should_match = (type == kTransportLocal);
172 
173         EXPECT_EQ(should_match, t.MatchesTarget("100.100.100.100"));
174         EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100"));
175         EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100:5555"));
176         EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100"));
177         EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100:5555"));
178 
179         // Wrong protocol, hostname, or port should never match.
180         EXPECT_FALSE(t.MatchesTarget("100.100.100"));
181         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:"));
182         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:-1"));
183         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:5554"));
184         EXPECT_FALSE(t.MatchesTarget("abc:100.100.100.100"));
185     }
186 }
187 #endif
188