Commit a7787f4c authored by Luum Habtemariam's avatar Luum Habtemariam Committed by Commit Bot

PrinterInstaller refactor

- Changed interface from ipp_t* -> std::string
- Removed virtual abstraction since there are no other implementations
- Updated tests

Bug: chromium:945409
Test: unittests pass
Change-Id: Icd7094c1f3b8f07b0dac295186e0e839ce093478
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1671928Reviewed-by: default avatarSean Kau <skau@chromium.org>
Commit-Queue: Luum Habtemariam <luum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#671519}
parent 6dc30560
...@@ -19,49 +19,20 @@ ...@@ -19,49 +19,20 @@
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
namespace cups_proxy { namespace cups_proxy {
namespace {
using CupsProxyServiceDelegate = chromeos::printing::CupsProxyServiceDelegate; PrinterInstaller::PrinterInstaller(
base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate)
class PrinterInstallerImpl : public PrinterInstaller { : delegate_(std::move(delegate)) {
public:
explicit PrinterInstallerImpl(
base::WeakPtr<CupsProxyServiceDelegate> delegate);
~PrinterInstallerImpl() override = default;
void InstallPrinterIfNeeded(ipp_t* ipp, InstallPrinterCallback cb) override;
private:
void OnInstallPrinter(InstallPrinterCallback cb, bool success);
void Finish(InstallPrinterCallback cb, InstallPrinterResult res);
// Service delegate granting access to printing stack dependencies.
base::WeakPtr<CupsProxyServiceDelegate> delegate_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<PrinterInstallerImpl> weak_factory_;
};
} // namespace
PrinterInstallerImpl::PrinterInstallerImpl(
base::WeakPtr<CupsProxyServiceDelegate> delegate)
: delegate_(std::move(delegate)), weak_factory_(this) {
DETACH_FROM_SEQUENCE(sequence_checker_); DETACH_FROM_SEQUENCE(sequence_checker_);
} }
void PrinterInstallerImpl::InstallPrinterIfNeeded(ipp_t* ipp, PrinterInstaller::~PrinterInstaller() = default;
void PrinterInstaller::InstallPrinter(std::string printer_id,
InstallPrinterCallback cb) { InstallPrinterCallback cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto printer_uuid = GetPrinterId(ipp); auto printer = delegate_->GetPrinter(printer_id);
if (!printer_uuid) {
Finish(std::move(cb), InstallPrinterResult::kNoPrintersFound);
return;
}
auto printer = delegate_->GetPrinter(*printer_uuid);
if (!printer) { if (!printer) {
// If the requested printer DNE, we proxy to CUPSd and allow it to // If the requested printer DNE, we proxy to CUPSd and allow it to
// handle the error. // handle the error.
...@@ -76,13 +47,13 @@ void PrinterInstallerImpl::InstallPrinterIfNeeded(ipp_t* ipp, ...@@ -76,13 +47,13 @@ void PrinterInstallerImpl::InstallPrinterIfNeeded(ipp_t* ipp,
// Install printer. // Install printer.
delegate_->SetupPrinter( delegate_->SetupPrinter(
*printer, base::BindOnce(&PrinterInstallerImpl::OnInstallPrinter, *printer, base::BindOnce(&PrinterInstaller::OnInstallPrinter,
weak_factory_.GetWeakPtr(), std::move(cb))); weak_factory_.GetWeakPtr(), std::move(cb)));
} }
// TODO(crbug.com/945409): Test whether we need to call // TODO(crbug.com/945409): Test whether we need to call
// CupsPrintersManager::PrinterInstalled here. // CupsPrintersManager::PrinterInstalled here.
void PrinterInstallerImpl::OnInstallPrinter(InstallPrinterCallback cb, void PrinterInstaller::OnInstallPrinter(InstallPrinterCallback cb,
bool success) { bool success) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -91,16 +62,10 @@ void PrinterInstallerImpl::OnInstallPrinter(InstallPrinterCallback cb, ...@@ -91,16 +62,10 @@ void PrinterInstallerImpl::OnInstallPrinter(InstallPrinterCallback cb,
: InstallPrinterResult::kPrinterInstallationFailure); : InstallPrinterResult::kPrinterInstallationFailure);
} }
void PrinterInstallerImpl::Finish(InstallPrinterCallback cb, void PrinterInstaller::Finish(InstallPrinterCallback cb,
InstallPrinterResult res) { InstallPrinterResult res) {
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(cb), res)); FROM_HERE, base::BindOnce(std::move(cb), res));
} }
// static
std::unique_ptr<PrinterInstaller> PrinterInstaller::Create(
base::WeakPtr<CupsProxyServiceDelegate> delegate) {
return std::make_unique<PrinterInstallerImpl>(std::move(delegate));
}
} // namespace cups_proxy } // namespace cups_proxy
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <cups/cups.h> #include <cups/cups.h>
#include <memory> #include <memory>
#include <string>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -18,9 +19,6 @@ namespace cups_proxy { ...@@ -18,9 +19,6 @@ namespace cups_proxy {
enum class InstallPrinterResult { enum class InstallPrinterResult {
kSuccess = 0, kSuccess = 0,
// Couldn't find any printers referenced by the incoming request.
kNoPrintersFound,
// Referenced printer is unknown to Chrome. // Referenced printer is unknown to Chrome.
kUnknownPrinterFound, kUnknownPrinterFound,
kPrinterInstallationFailure, kPrinterInstallationFailure,
...@@ -34,16 +32,23 @@ using InstallPrinterCallback = base::OnceCallback<void(InstallPrinterResult)>; ...@@ -34,16 +32,23 @@ using InstallPrinterCallback = base::OnceCallback<void(InstallPrinterResult)>;
// sequenced context. // sequenced context.
class PrinterInstaller { class PrinterInstaller {
public: public:
// Factory function. explicit PrinterInstaller(
static std::unique_ptr<PrinterInstaller> Create(
base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate); base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate);
~PrinterInstaller();
virtual ~PrinterInstaller() = default;
// Pre-installs any printers required by |ipp| into the CUPS daemon, as // Pre-installs any printers required by |ipp| into the CUPS daemon, as
// needed. |cb| will be run on this instance's sequenced context. // needed. |cb| will be run on this instance's sequenced context.
virtual void InstallPrinterIfNeeded(ipp_t* ipp, void InstallPrinter(std::string printer_id, InstallPrinterCallback cb);
InstallPrinterCallback cb) = 0;
private:
void OnInstallPrinter(InstallPrinterCallback cb, bool success);
void Finish(InstallPrinterCallback cb, InstallPrinterResult res);
// Service delegate granting access to printing stack dependencies.
base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<PrinterInstaller> weak_factory_{this};
}; };
} // namespace cups_proxy } // namespace cups_proxy
......
...@@ -37,6 +37,8 @@ class FakeServiceDelegate ...@@ -37,6 +37,8 @@ class FakeServiceDelegate
installed_printers_.insert({printer.id(), false}); installed_printers_.insert({printer.id(), false});
} }
void FailSetupPrinter() { fail_printer_setup_ = true; }
// Service delegate overrides. // Service delegate overrides.
bool IsPrinterInstalled(const Printer& printer) override { bool IsPrinterInstalled(const Printer& printer) override {
if (!base::Contains(installed_printers_, printer.id())) { if (!base::Contains(installed_printers_, printer.id())) {
...@@ -57,6 +59,10 @@ class FakeServiceDelegate ...@@ -57,6 +59,10 @@ class FakeServiceDelegate
void SetupPrinter( void SetupPrinter(
const Printer& printer, const Printer& printer,
chromeos::printing::PrinterSetupCallback callback) override { chromeos::printing::PrinterSetupCallback callback) override {
if (fail_printer_setup_) {
return std::move(callback).Run(false);
}
// PrinterInstaller is expected to have checked if |printer| is already // PrinterInstaller is expected to have checked if |printer| is already
// installed before trying setup. // installed before trying setup.
if (IsPrinterInstalled(printer)) { if (IsPrinterInstalled(printer)) {
...@@ -70,43 +76,42 @@ class FakeServiceDelegate ...@@ -70,43 +76,42 @@ class FakeServiceDelegate
private: private:
std::map<std::string, bool> installed_printers_; std::map<std::string, bool> installed_printers_;
// Conditions whether calls to SetupPrinter succeed.
bool fail_printer_setup_ = false;
}; };
class PrinterInstallerTest : public testing::Test { class PrinterInstallerTest : public testing::Test {
public: public:
PrinterInstallerTest() : weak_factory_(this) { PrinterInstallerTest() : weak_factory_(this) {
delegate_ = std::make_unique<FakeServiceDelegate>(); delegate_ = std::make_unique<FakeServiceDelegate>();
printer_installer_ = PrinterInstaller::Create(delegate_->GetWeakPtr()); printer_installer_ =
std::make_unique<PrinterInstaller>(delegate_->GetWeakPtr());
} }
~PrinterInstallerTest() override = default; ~PrinterInstallerTest() override = default;
bool RunInstallPrinterIfNeeded(ipp_t* ipp, Printer to_install) { InstallPrinterResult RunInstallPrinter(std::string printer_id) {
bool success = false; InstallPrinterResult ret;
printer_installer_->InstallPrinterIfNeeded(
ipp, base::BindOnce(&PrinterInstallerTest::OnRunInstallPrinterIfNeeded, base::RunLoop run_loop;
weak_factory_.GetWeakPtr(), &success, printer_installer_->InstallPrinter(
std::move(to_install))); printer_id, base::BindOnce(&PrinterInstallerTest::OnRunInstallPrinter,
scoped_task_environment_.RunUntilIdle(); weak_factory_.GetWeakPtr(),
return success; run_loop.QuitClosure(), &ret));
run_loop.Run();
return ret;
} }
protected: protected:
base::test::ScopedTaskEnvironment scoped_task_environment_; base::test::ScopedTaskEnvironment scoped_task_environment_;
void OnRunInstallPrinterIfNeeded(bool* ret, void OnRunInstallPrinter(base::OnceClosure finish_cb,
Printer to_install, InstallPrinterResult* ret,
InstallPrinterResult result) { InstallPrinterResult result) {
if (result != InstallPrinterResult::kSuccess) { *ret = result;
return; std::move(finish_cb).Run();
}
// If printer wasn't installed, fail.
if (!delegate_->IsPrinterInstalled(to_install)) {
return;
}
*ret = true;
} }
// Backend fake driving the PrinterInstaller. // Backend fake driving the PrinterInstaller.
...@@ -119,33 +124,23 @@ class PrinterInstallerTest : public testing::Test { ...@@ -119,33 +124,23 @@ class PrinterInstallerTest : public testing::Test {
base::WeakPtrFactory<PrinterInstallerTest> weak_factory_; base::WeakPtrFactory<PrinterInstallerTest> weak_factory_;
}; };
// Return a valid ScopedIppPtr that correctly references |id| in
// the printer-uri field.
::printing::ScopedIppPtr MakeIppReferencingPrinters(const std::string& id) {
::printing::ScopedIppPtr ret = ::printing::WrapIpp(ippNew());
std::string uri = "ipp://localhost/printers/" + id;
ippAddString(ret.get(), IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri", NULL,
uri.c_str());
return ret;
}
// Standard install known printer workflow. // Standard install known printer workflow.
TEST_F(PrinterInstallerTest, SimpleSanityTest) { TEST_F(PrinterInstallerTest, SimpleSanityTest) {
Printer to_install(kGenericGUID); Printer to_install(kGenericGUID);
delegate_->AddPrinter(to_install); delegate_->AddPrinter(to_install);
auto ipp = MakeIppReferencingPrinters(to_install.id()); auto ret = RunInstallPrinter(kGenericGUID);
EXPECT_TRUE(RunInstallPrinterIfNeeded(ipp.get(), std::move(to_install))); EXPECT_EQ(ret, InstallPrinterResult::kSuccess);
EXPECT_TRUE(delegate_->IsPrinterInstalled(to_install));
} }
// Should fail to install an unknown(previously unseen) printer. // Should fail to install an unknown(previously unseen) printer.
TEST_F(PrinterInstallerTest, UnknownPrinter) { TEST_F(PrinterInstallerTest, UnknownPrinter) {
Printer to_install(kGenericGUID); Printer to_install(kGenericGUID);
auto ipp = MakeIppReferencingPrinters(to_install.id()); auto ret = RunInstallPrinter(kGenericGUID);
EXPECT_FALSE(RunInstallPrinterIfNeeded(ipp.get(), std::move(to_install))); EXPECT_EQ(ret, InstallPrinterResult::kUnknownPrinterFound);
EXPECT_FALSE(delegate_->IsPrinterInstalled(to_install));
} }
// Ensure we never setup a printer that's already installed. // Ensure we never setup a printer that's already installed.
...@@ -153,12 +148,23 @@ TEST_F(PrinterInstallerTest, InstallPrinterTwice) { ...@@ -153,12 +148,23 @@ TEST_F(PrinterInstallerTest, InstallPrinterTwice) {
Printer to_install(kGenericGUID); Printer to_install(kGenericGUID);
delegate_->AddPrinter(to_install); delegate_->AddPrinter(to_install);
auto ipp = MakeIppReferencingPrinters(to_install.id()); auto ret = RunInstallPrinter(kGenericGUID);
EXPECT_TRUE(RunInstallPrinterIfNeeded(ipp.get(), to_install)); EXPECT_EQ(ret, InstallPrinterResult::kSuccess);
// |printer_installer_| should notice printer is already installed and bail // |printer_installer_| should notice printer is already installed and bail
// out. If it attempts setup, FakeServiceDelegate will fail the request. // out. If it attempts setup, FakeServiceDelegate will fail the request.
EXPECT_TRUE(RunInstallPrinterIfNeeded(ipp.get(), to_install)); ret = RunInstallPrinter(kGenericGUID);
EXPECT_EQ(ret, InstallPrinterResult::kSuccess);
}
// Checks for correct response to failed SetupPrinter call.
TEST_F(PrinterInstallerTest, SetupPrinterFailure) {
Printer to_install(kGenericGUID);
delegate_->AddPrinter(to_install);
delegate_->FailSetupPrinter();
auto ret = RunInstallPrinter(kGenericGUID);
EXPECT_EQ(ret, InstallPrinterResult::kPrinterInstallationFailure);
} }
} // namespace } // namespace
......
...@@ -23,6 +23,7 @@ static const size_t kHttpMaxBufferSize = 2048; ...@@ -23,6 +23,7 @@ static const size_t kHttpMaxBufferSize = 2048;
// If |ipp| refers to a printer, we return the associated printer_id. // If |ipp| refers to a printer, we return the associated printer_id.
// Note: Expects the printer id to be embedded in the resource field of the // Note: Expects the printer id to be embedded in the resource field of the
// 'printer-uri' IPP attribute. // 'printer-uri' IPP attribute.
// TODO(crbug.com/945409): Add testing suite.
base::Optional<std::string> GetPrinterId(ipp_t* ipp); base::Optional<std::string> GetPrinterId(ipp_t* ipp);
} // namespace cups_proxy } // namespace cups_proxy
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment