| // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "p2p/client/fake_service_finder.h" |
| |
| #include <set> |
| |
| #include <base/logging.h> |
| |
| using std::map; |
| using std::set; |
| using std::string; |
| using std::vector; |
| |
| namespace p2p { |
| |
| namespace client { |
| |
| FakeServiceFinder::FakeServiceFinder() |
| : num_lookup_calls_(0), service_filtered_(false) {} |
| |
| FakeServiceFinder::~FakeServiceFinder() = default; |
| |
| vector<const Peer*> FakeServiceFinder::GetPeersForFile( |
| const string& file) const { |
| vector<const Peer*> res; |
| if (service_filtered_) |
| return res; |
| |
| for (auto const& peer : peers_) { |
| if (peer.files.find(file) != peer.files.end()) |
| res.push_back(&peer); |
| } |
| return res; |
| } |
| |
| vector<string> FakeServiceFinder::AvailableFiles() const { |
| if (service_filtered_) |
| return vector<string>(); |
| |
| set<string> retset; |
| for (auto const& peer : peers_) { |
| for (auto const& file : peer.files) { |
| retset.insert(file.first); |
| } |
| } |
| return vector<string>(retset.begin(), retset.end()); |
| } |
| |
| int FakeServiceFinder::NumTotalConnections() const { |
| int res = 0; |
| if (service_filtered_) |
| return res; |
| |
| for (auto const& peer : peers_) |
| res += peer.num_connections; |
| return res; |
| } |
| |
| int FakeServiceFinder::NumTotalPeers() const { |
| if (service_filtered_) |
| return 0; |
| return peers_.size(); |
| } |
| |
| bool FakeServiceFinder::Lookup() { |
| num_lookup_calls_++; |
| |
| // Execute scheduled calls. |
| if (set_peer_connections_calls_.find(num_lookup_calls_) != |
| set_peer_connections_calls_.end()) { |
| for (auto const& params : set_peer_connections_calls_[num_lookup_calls_]) |
| SetPeerConnections(params.peer_id, params.connections); |
| set_peer_connections_calls_.erase(num_lookup_calls_); |
| } |
| |
| if (remove_available_file_calls_.find(num_lookup_calls_) != |
| remove_available_file_calls_.end()) { |
| for (auto const& params : remove_available_file_calls_[num_lookup_calls_]) |
| RemoveAvailableFile(params); |
| remove_available_file_calls_.erase(num_lookup_calls_); |
| } |
| |
| if (peer_share_file_calls_.find(num_lookup_calls_) != |
| peer_share_file_calls_.end()) { |
| for (auto const& params : peer_share_file_calls_[num_lookup_calls_]) |
| PeerShareFile(params.peer_id, params.file, params.size); |
| peer_share_file_calls_.erase(num_lookup_calls_); |
| } |
| |
| return !service_filtered_; |
| } |
| |
| void FakeServiceFinder::Abort() {} |
| |
| int FakeServiceFinder::GetNumLookupCalls() { |
| return num_lookup_calls_; |
| } |
| |
| void FakeServiceFinder::SetServiceFiltered(bool filtered) { |
| service_filtered_ = filtered; |
| } |
| |
| int FakeServiceFinder::NewPeer(string address, bool is_ipv6, uint16_t port) { |
| peers_.push_back((Peer){.address = address, |
| .is_ipv6 = is_ipv6, |
| .port = port, |
| .num_connections = 0, |
| .files = map<string, size_t>()}); |
| return peers_.size() - 1; |
| } |
| |
| bool FakeServiceFinder::SetPeerConnections(int peer_id, int connections) { |
| if (peer_id < 0 || static_cast<unsigned>(peer_id) >= peers_.size()) { |
| LOG(ERROR) << "Invalid peer_id provided: " << peer_id << "."; |
| return false; |
| } |
| peers_[peer_id].num_connections = connections; |
| return true; |
| } |
| |
| bool FakeServiceFinder::SetPeerConnectionsOnLookup(int at_call, |
| int peer_id, |
| int connections) { |
| if (at_call < num_lookup_calls_) |
| return false; |
| if (at_call == num_lookup_calls_) |
| return SetPeerConnections(peer_id, connections); |
| set_peer_connections_calls_[at_call].push_back( |
| (SetPeerConnectionsCall){.peer_id = peer_id, .connections = connections}); |
| return true; |
| } |
| |
| bool FakeServiceFinder::PeerShareFile(int peer_id, |
| const string& file, |
| size_t size) { |
| if (peer_id < 0 || static_cast<unsigned>(peer_id) >= peers_.size()) { |
| LOG(ERROR) << "Invalid peer_id provided: " << peer_id << "."; |
| return false; |
| } |
| peers_[peer_id].files[file] = size; |
| return true; |
| } |
| |
| bool FakeServiceFinder::PeerShareFileOnLookup(int at_call, |
| int peer_id, |
| const std::string& file, |
| size_t size) { |
| if (at_call < num_lookup_calls_) |
| return false; |
| if (at_call == num_lookup_calls_) |
| return PeerShareFile(peer_id, file, size); |
| peer_share_file_calls_[at_call].push_back( |
| (PeerShareFileCall){.peer_id = peer_id, .file = file, .size = size}); |
| return true; |
| } |
| |
| bool FakeServiceFinder::RemoveAvailableFile(const string& file) { |
| int removed = 0; |
| |
| for (auto& peer : peers_) { |
| map<string, size_t>::iterator file_it = peer.files.find(file); |
| if (file_it != peer.files.end()) { |
| peer.files.erase(file_it); |
| removed++; |
| } |
| } |
| |
| if (!removed) { |
| LOG(ERROR) << "Removing unexisting file <" << file << ">."; |
| return false; |
| } |
| return true; |
| } |
| |
| bool FakeServiceFinder::RemoveAvailableFileOnLookup(int at_call, |
| const std::string& file) { |
| if (at_call < num_lookup_calls_) |
| return false; |
| if (at_call == num_lookup_calls_) |
| return RemoveAvailableFile(file); |
| // Ensure the RemoveAvailableFile() calls before the PeerShareFile() ones. |
| if (peer_share_file_calls_.find(at_call) != peer_share_file_calls_.end()) |
| return false; |
| remove_available_file_calls_[at_call].push_back(file); |
| return true; |
| } |
| |
| } // namespace client |
| |
| } // namespace p2p |