blob: 31e91ab7a6c4e6be34d1e1aec1d742b93ff1f2f5 [file] [log] [blame]
// Copyright (c) 2019 The Chromium 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 "net/url_request/url_request_ftp_job.h"
#include <memory>
#include "base/test/metrics/histogram_tester.h"
#include "net/base/auth.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/ftp/ftp_auth_cache.h"
#include "net/ftp/ftp_response_info.h"
#include "net/ftp/ftp_transaction.h"
#include "net/ftp/ftp_transaction_factory.h"
#include "net/test/test_with_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
class MockFtpTransaction : public FtpTransaction {
public:
MockFtpTransaction(int start_return_value,
int read_return_value,
bool needs_auth,
std::vector<int> restart_return_values)
: start_return_value_(start_return_value),
read_return_value_(read_return_value),
restart_return_values_(restart_return_values),
restart_index_(0) {
response_.needs_auth = needs_auth;
}
~MockFtpTransaction() override {}
int Start(const FtpRequestInfo* request_info,
CompletionOnceCallback callback,
const NetLogWithSource& net_log,
const NetworkTrafficAnnotationTag& traffic_annotation) override {
return start_return_value_;
}
int RestartWithAuth(const AuthCredentials& credentials,
CompletionOnceCallback callback) override {
CHECK(restart_index_ < restart_return_values_.size());
return restart_return_values_[restart_index_++];
}
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override {
return read_return_value_;
}
const FtpResponseInfo* GetResponseInfo() const override { return &response_; }
LoadState GetLoadState() const override { return LOAD_STATE_IDLE; }
uint64_t GetUploadProgress() const override { return 0; }
private:
FtpResponseInfo response_;
int start_return_value_;
int read_return_value_;
std::vector<int> restart_return_values_;
unsigned int restart_index_;
DISALLOW_COPY_AND_ASSIGN(MockFtpTransaction);
};
class MockFtpTransactionFactory : public FtpTransactionFactory {
public:
MockFtpTransactionFactory(int start_return_value,
int read_return_value,
bool needs_auth,
std::vector<int> restart_return_values)
: start_return_value_(start_return_value),
read_return_value_(read_return_value),
needs_auth_(needs_auth),
restart_return_values_(restart_return_values) {}
~MockFtpTransactionFactory() override {}
std::unique_ptr<FtpTransaction> CreateTransaction() override {
return std::make_unique<MockFtpTransaction>(start_return_value_,
read_return_value_, needs_auth_,
restart_return_values_);
}
void Suspend(bool suspend) override {}
private:
int start_return_value_;
int read_return_value_;
bool needs_auth_;
std::vector<int> restart_return_values_;
DISALLOW_COPY_AND_ASSIGN(MockFtpTransactionFactory);
};
class MockURLRequestFtpJobFactory : public URLRequestJobFactory {
public:
MockURLRequestFtpJobFactory(int start_return_value,
int read_return_value,
bool needs_auth,
std::vector<int> restart_return_values)
: auth_cache(new FtpAuthCache()),
factory(new MockFtpTransactionFactory(start_return_value,
read_return_value,
needs_auth,
restart_return_values)) {}
~MockURLRequestFtpJobFactory() override {
delete auth_cache;
delete factory;
}
URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
URLRequest* request,
NetworkDelegate* network_delegate) const override {
return new URLRequestFtpJob(request, network_delegate, factory, auth_cache);
}
bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == "ftp";
}
bool IsSafeRedirectTarget(const GURL& location) const override {
return true;
}
private:
FtpAuthCache* auth_cache;
MockFtpTransactionFactory* factory;
DISALLOW_COPY_AND_ASSIGN(MockURLRequestFtpJobFactory);
};
using UrlRequestFtpJobTest = TestWithTaskEnvironment;
TEST_F(UrlRequestFtpJobTest, HistogramLogSuccessNoAuth) {
base::HistogramTester histograms;
MockURLRequestFtpJobFactory url_request_ftp_job_factory(OK, OK, false, {OK});
TestNetworkDelegate network_delegate;
TestURLRequestContext context(true);
context.set_network_delegate(&network_delegate);
context.set_job_factory(&url_request_ftp_job_factory);
context.Init();
TestDelegate test_delegate;
std::unique_ptr<URLRequest> r(context.CreateRequest(
GURL("ftp://example.test/"), RequestPriority::DEFAULT_PRIORITY,
&test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
r->Start();
test_delegate.RunUntilComplete();
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessNoAuth, 1);
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessAuth, 0);
histograms.ExpectBucketCount("Net.FTP.StartResult", FTPStartResult::kFailed,
0);
}
TEST_F(UrlRequestFtpJobTest, HistogramLogSuccessAuth) {
base::HistogramTester histograms;
MockURLRequestFtpJobFactory url_request_ftp_job_factory(
ERR_FAILED, ERR_FAILED, true, {OK});
TestNetworkDelegate network_delegate;
TestURLRequestContext context(true);
context.set_network_delegate(&network_delegate);
context.set_job_factory(&url_request_ftp_job_factory);
context.Init();
TestDelegate test_delegate;
test_delegate.set_credentials(
AuthCredentials(base::ASCIIToUTF16("user"), base::ASCIIToUTF16("pass")));
std::unique_ptr<URLRequest> r(context.CreateRequest(
GURL("ftp://example.test/"), RequestPriority::DEFAULT_PRIORITY,
&test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
r->Start();
test_delegate.RunUntilComplete();
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessNoAuth, 0);
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessAuth, 1);
histograms.ExpectBucketCount("Net.FTP.StartResult", FTPStartResult::kFailed,
0);
}
TEST_F(UrlRequestFtpJobTest, HistogramLogFailed) {
base::HistogramTester histograms;
MockURLRequestFtpJobFactory url_request_ftp_job_factory(
ERR_FAILED, ERR_FAILED, false, {ERR_FAILED});
TestNetworkDelegate network_delegate;
TestURLRequestContext context(true);
context.set_network_delegate(&network_delegate);
context.set_job_factory(&url_request_ftp_job_factory);
context.Init();
TestDelegate test_delegate;
std::unique_ptr<URLRequest> r(context.CreateRequest(
GURL("ftp://example.test/"), RequestPriority::DEFAULT_PRIORITY,
&test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
r->Start();
test_delegate.RunUntilComplete();
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessNoAuth, 0);
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessAuth, 0);
histograms.ExpectBucketCount("Net.FTP.StartResult", FTPStartResult::kFailed,
1);
}
TEST_F(UrlRequestFtpJobTest, HistogramLogFailedInvalidAuthThenSucceed) {
base::HistogramTester histograms;
MockURLRequestFtpJobFactory url_request_ftp_job_factory(
ERR_FAILED, ERR_FAILED, true, {ERR_ACCESS_DENIED, OK});
TestNetworkDelegate network_delegate;
TestURLRequestContext context(true);
context.set_network_delegate(&network_delegate);
context.set_job_factory(&url_request_ftp_job_factory);
context.Init();
TestDelegate test_delegate;
test_delegate.set_credentials(
AuthCredentials(base::ASCIIToUTF16("user"), base::ASCIIToUTF16("pass")));
std::unique_ptr<URLRequest> r(context.CreateRequest(
GURL("ftp://example.test/"), RequestPriority::DEFAULT_PRIORITY,
&test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
r->Start();
test_delegate.RunUntilComplete();
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessNoAuth, 0);
histograms.ExpectBucketCount("Net.FTP.StartResult",
FTPStartResult::kSuccessAuth, 1);
histograms.ExpectBucketCount("Net.FTP.StartResult", FTPStartResult::kFailed,
1);
}
} // namespace
} // namespace net