chromium/chrome/browser/ash/smb_client/discovery/network_scanner_unittest.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/smb_client/discovery/network_scanner.h"

#include <map>
#include <string>
#include <utility>

#include "base/functional/bind.h"
#include "chrome/browser/ash/smb_client/discovery/in_memory_host_locator.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash::smb_client {

namespace {

// Expects |actual_hosts| to equal |expected_hosts|.
void ExpectMapEntriesEqual(const HostMap& expected_hosts,
                           bool success,
                           const HostMap& actual_hosts) {
  EXPECT_TRUE(success);
  EXPECT_EQ(expected_hosts, actual_hosts);
}

void ExpectFailure(bool success, const HostMap& actual_hosts) {
  EXPECT_FALSE(success);
  EXPECT_TRUE(actual_hosts.empty());
}

}  // namespace

class NetworkScannerTest : public testing::Test {
 public:
  NetworkScannerTest() = default;

  NetworkScannerTest(const NetworkScannerTest&) = delete;
  NetworkScannerTest& operator=(const NetworkScannerTest&) = delete;

  ~NetworkScannerTest() override = default;

 protected:
  void RegisterHostLocatorWithHosts(const HostMap& hosts) {
    std::unique_ptr<InMemoryHostLocator> host_locator =
        std::make_unique<InMemoryHostLocator>();
    host_locator->AddHosts(hosts);
    scanner_.RegisterHostLocator(std::move(host_locator));
  }

  void ExpectHostMapEqual(const HostMap& expected_hosts) {
    scanner_.FindHostsInNetwork(
        base::BindOnce(&ExpectMapEntriesEqual, expected_hosts));
  }

  void ExpectCallFailure() {
    scanner_.FindHostsInNetwork(base::BindOnce(&ExpectFailure));
  }

  void ExpectResolvedHostEquals(const std::string& expected,
                                const std::string& host) {
    EXPECT_EQ(expected, scanner_.ResolveHost(host).ToString());
  }

  // Registers |hosts| with a host locator and call FindHostsInNetwork() which
  // caches the results.
  void RegisterAndCacheHosts(const HostMap& hosts) {
    RegisterHostLocatorWithHosts(hosts);
    ExpectHostMapEqual(hosts);
  }

 private:
  NetworkScanner scanner_;
};

TEST_F(NetworkScannerTest, SuccessIsFalseAndHostsMapIsEmptyWithNoLocator) {
  ExpectCallFailure();
}

TEST_F(NetworkScannerTest, ShouldFindNoHostsWithOneLocator) {
  RegisterHostLocatorWithHosts(HostMap());

  ExpectHostMapEqual(HostMap());
}

TEST_F(NetworkScannerTest, ShouldFindNoHostsWithMultipleLocators) {
  RegisterHostLocatorWithHosts(HostMap());
  RegisterHostLocatorWithHosts(HostMap());

  ExpectHostMapEqual(HostMap());
}

TEST_F(NetworkScannerTest, ShouldFindOneHostWithOneLocator) {
  HostMap hosts;
  hosts["share1"] = {1, 2, 3, 4};
  RegisterHostLocatorWithHosts(hosts);

  ExpectHostMapEqual(hosts);
}

TEST_F(NetworkScannerTest, ShouldFindMultipleHostsWithOneLocator) {
  HostMap hosts;
  hosts["share1"] = {1, 2, 3, 4};
  hosts["share2"] = {5, 6, 7, 8};
  RegisterHostLocatorWithHosts(hosts);

  ExpectHostMapEqual(hosts);
}

TEST_F(NetworkScannerTest, ShouldFindMultipleHostsWithMultipleLocators) {
  HostMap hosts1;
  hosts1["share1"] = {1, 2, 3, 4};
  hosts1["share2"] = {5, 6, 7, 8};
  RegisterHostLocatorWithHosts(hosts1);

  HostMap hosts2;
  hosts2["share3"] = {11, 12, 13, 14};
  hosts2["share4"] = {15, 16, 17, 18};
  RegisterHostLocatorWithHosts(hosts2);

  HostMap expected;
  expected["share1"] = {1, 2, 3, 4};
  expected["share2"] = {5, 6, 7, 8};
  expected["share3"] = {11, 12, 13, 14};
  expected["share4"] = {15, 16, 17, 18};

  ExpectHostMapEqual(expected);
}

TEST_F(NetworkScannerTest, ShouldResolveMultipleHostsWithSameAddress) {
  HostMap hosts1;
  hosts1["share1"] = {1, 2, 3, 4};
  hosts1["share2"] = {5, 6, 7, 8};
  RegisterHostLocatorWithHosts(hosts1);

  HostMap hosts2;
  hosts2["share2"] = {11, 12, 13, 14};
  hosts2["share3"] = {15, 16, 17, 18};
  RegisterHostLocatorWithHosts(hosts2);

  // share2 should have the value from host1 since it is found first.
  HostMap expected;
  expected["share1"] = {1, 2, 3, 4};
  expected["share2"] = {5, 6, 7, 8};
  expected["share3"] = {15, 16, 17, 18};

  ExpectHostMapEqual(expected);
}

TEST_F(NetworkScannerTest, ResolveHostReturnsEmptyStringIfNoHostFound) {
  HostMap hosts;
  // Register a hostlocator with no hosts.
  RegisterAndCacheHosts(hosts);

  // Returns an empty string since host could not be resolved.
  ExpectResolvedHostEquals("", "server");
}

TEST_F(NetworkScannerTest, ResolveHostResolvesHostsFound) {
  HostMap hosts;
  hosts["share1"] = {1, 2, 3, 4};
  hosts["share2"] = {4, 5, 6, 7};
  RegisterAndCacheHosts(hosts);

  ExpectResolvedHostEquals("1.2.3.4", "share1");
  ExpectResolvedHostEquals("4.5.6.7", "share2");

  // Returns an empty string since host could not be resolved.
  ExpectResolvedHostEquals("", "share3");
}

TEST_F(NetworkScannerTest, ResolveHostWithUppercaseHost) {
  HostMap hosts;
  hosts["share1"] = {1, 2, 3, 4};
  RegisterAndCacheHosts(hosts);

  ExpectResolvedHostEquals("1.2.3.4", "SHARE1");
}

TEST_F(NetworkScannerTest, HostsAreStoredAsLowercase) {
  HostMap hosts;
  hosts["SHARE1"] = {1, 2, 3, 4};
  hosts["sHaRe2"] = {11, 12, 13, 14};
  hosts["Share3"] = {21, 22, 23, 24};
  RegisterHostLocatorWithHosts(hosts);

  // expected_hosts should have all lowercase hosts.
  HostMap expected_hosts;
  expected_hosts["share1"] = {1, 2, 3, 4};
  expected_hosts["share2"] = {11, 12, 13, 14};
  expected_hosts["share3"] = {21, 22, 23, 24};
  ExpectHostMapEqual(expected_hosts);

  ExpectResolvedHostEquals("1.2.3.4", "share1");
  ExpectResolvedHostEquals("11.12.13.14", "share2");
  ExpectResolvedHostEquals("21.22.23.24", "share3");
}

}  // namespace ash::smb_client