Home | History | Annotate | Download | only in adb
      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 
     23 class TransportSetup {
     24 public:
     25   TransportSetup() {
     26 #ifdef _WIN32
     27     // Use extern instead of including sysdeps.h which brings in various macros
     28     // that conflict with APIs used in this file.
     29     extern void adb_sysdeps_init(void);
     30     adb_sysdeps_init();
     31 #else
     32     // adb_sysdeps_init() is an inline function that we cannot link against.
     33 #endif
     34   }
     35 };
     36 
     37 // Static initializer will call adb_sysdeps_init() before main() to initialize
     38 // the transport mutex before it is used in the tests. Alternatives would be to
     39 // use __attribute__((constructor)) here or to use that or a static initializer
     40 // for adb_sysdeps_init() itself in sysdeps_win32.cpp (caveats of unclear
     41 // init order), or to use a test fixture whose SetUp() could do the init once.
     42 static TransportSetup g_TransportSetup;
     43 
     44 TEST(transport, kick_transport) {
     45   atransport t;
     46   static size_t kick_count;
     47   kick_count = 0;
     48   // Mutate some member so we can test that the function is run.
     49   t.SetKickFunction([](atransport* trans) { kick_count++; });
     50   ASSERT_FALSE(t.IsKicked());
     51   t.Kick();
     52   ASSERT_TRUE(t.IsKicked());
     53   ASSERT_EQ(1u, kick_count);
     54   // A transport can only be kicked once.
     55   t.Kick();
     56   ASSERT_TRUE(t.IsKicked());
     57   ASSERT_EQ(1u, kick_count);
     58 }
     59 
     60 static void DisconnectFunc(void* arg, atransport*) {
     61     int* count = reinterpret_cast<int*>(arg);
     62     ++*count;
     63 }
     64 
     65 TEST(transport, RunDisconnects) {
     66     atransport t;
     67     // RunDisconnects() can be called with an empty atransport.
     68     t.RunDisconnects();
     69 
     70     int count = 0;
     71     adisconnect disconnect;
     72     disconnect.func = DisconnectFunc;
     73     disconnect.opaque = &count;
     74     t.AddDisconnect(&disconnect);
     75     t.RunDisconnects();
     76     ASSERT_EQ(1, count);
     77 
     78     // disconnect should have been removed automatically.
     79     t.RunDisconnects();
     80     ASSERT_EQ(1, count);
     81 
     82     count = 0;
     83     t.AddDisconnect(&disconnect);
     84     t.RemoveDisconnect(&disconnect);
     85     t.RunDisconnects();
     86     ASSERT_EQ(0, count);
     87 }
     88 
     89 TEST(transport, SetFeatures) {
     90     atransport t;
     91     ASSERT_EQ(0U, t.features().size());
     92 
     93     t.SetFeatures(FeatureSetToString(FeatureSet{"foo"}));
     94     ASSERT_EQ(1U, t.features().size());
     95     ASSERT_TRUE(t.has_feature("foo"));
     96 
     97     t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar"}));
     98     ASSERT_EQ(2U, t.features().size());
     99     ASSERT_TRUE(t.has_feature("foo"));
    100     ASSERT_TRUE(t.has_feature("bar"));
    101 
    102     t.SetFeatures(FeatureSetToString(FeatureSet{"foo", "bar", "foo"}));
    103     ASSERT_EQ(2U, t.features().size());
    104     ASSERT_TRUE(t.has_feature("foo"));
    105     ASSERT_TRUE(t.has_feature("bar"));
    106 
    107     t.SetFeatures(FeatureSetToString(FeatureSet{"bar", "baz"}));
    108     ASSERT_EQ(2U, t.features().size());
    109     ASSERT_FALSE(t.has_feature("foo"));
    110     ASSERT_TRUE(t.has_feature("bar"));
    111     ASSERT_TRUE(t.has_feature("baz"));
    112 
    113     t.SetFeatures("");
    114     ASSERT_EQ(0U, t.features().size());
    115 }
    116 
    117 TEST(transport, parse_banner_no_features) {
    118     atransport t;
    119 
    120     parse_banner("host::", &t);
    121 
    122     ASSERT_EQ(0U, t.features().size());
    123     ASSERT_EQ(kCsHost, t.connection_state);
    124 
    125     ASSERT_EQ(nullptr, t.product);
    126     ASSERT_EQ(nullptr, t.model);
    127     ASSERT_EQ(nullptr, t.device);
    128 }
    129 
    130 TEST(transport, parse_banner_product_features) {
    131     atransport t;
    132 
    133     const char banner[] =
    134         "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;";
    135     parse_banner(banner, &t);
    136 
    137     ASSERT_EQ(kCsHost, t.connection_state);
    138 
    139     ASSERT_EQ(0U, t.features().size());
    140 
    141     ASSERT_EQ(std::string("foo"), t.product);
    142     ASSERT_EQ(std::string("bar"), t.model);
    143     ASSERT_EQ(std::string("baz"), t.device);
    144 }
    145 
    146 TEST(transport, parse_banner_features) {
    147     atransport t;
    148 
    149     const char banner[] =
    150         "host::ro.product.name=foo;ro.product.model=bar;ro.product.device=baz;"
    151         "features=woodly,doodly";
    152     parse_banner(banner, &t);
    153 
    154     ASSERT_EQ(kCsHost, t.connection_state);
    155 
    156     ASSERT_EQ(2U, t.features().size());
    157     ASSERT_TRUE(t.has_feature("woodly"));
    158     ASSERT_TRUE(t.has_feature("doodly"));
    159 
    160     ASSERT_EQ(std::string("foo"), t.product);
    161     ASSERT_EQ(std::string("bar"), t.model);
    162     ASSERT_EQ(std::string("baz"), t.device);
    163 }
    164 
    165 TEST(transport, test_matches_target) {
    166     std::string serial = "foo";
    167     std::string devpath = "/path/to/bar";
    168     std::string product = "test_product";
    169     std::string model = "test_model";
    170     std::string device = "test_device";
    171 
    172     atransport t;
    173     t.serial = &serial[0];
    174     t.devpath = &devpath[0];
    175     t.product = &product[0];
    176     t.model = &model[0];
    177     t.device = &device[0];
    178 
    179     // These tests should not be affected by the transport type.
    180     for (TransportType type : {kTransportAny, kTransportLocal}) {
    181         t.type = type;
    182 
    183         EXPECT_TRUE(t.MatchesTarget(serial));
    184         EXPECT_TRUE(t.MatchesTarget(devpath));
    185         EXPECT_TRUE(t.MatchesTarget("product:" + product));
    186         EXPECT_TRUE(t.MatchesTarget("model:" + model));
    187         EXPECT_TRUE(t.MatchesTarget("device:" + device));
    188 
    189         // Product, model, and device don't match without the prefix.
    190         EXPECT_FALSE(t.MatchesTarget(product));
    191         EXPECT_FALSE(t.MatchesTarget(model));
    192         EXPECT_FALSE(t.MatchesTarget(device));
    193     }
    194 }
    195 
    196 TEST(transport, test_matches_target_local) {
    197     std::string serial = "100.100.100.100:5555";
    198 
    199     atransport t;
    200     t.serial = &serial[0];
    201 
    202     // Network address matching should only be used for local transports.
    203     for (TransportType type : {kTransportAny, kTransportLocal}) {
    204         t.type = type;
    205         bool should_match = (type == kTransportLocal);
    206 
    207         EXPECT_EQ(should_match, t.MatchesTarget("100.100.100.100"));
    208         EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100"));
    209         EXPECT_EQ(should_match, t.MatchesTarget("tcp:100.100.100.100:5555"));
    210         EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100"));
    211         EXPECT_EQ(should_match, t.MatchesTarget("udp:100.100.100.100:5555"));
    212 
    213         // Wrong protocol, hostname, or port should never match.
    214         EXPECT_FALSE(t.MatchesTarget("100.100.100"));
    215         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:"));
    216         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:-1"));
    217         EXPECT_FALSE(t.MatchesTarget("100.100.100.100:5554"));
    218         EXPECT_FALSE(t.MatchesTarget("abc:100.100.100.100"));
    219     }
    220 }
    221