blob: 2d9a9c9fb187113ec0f440cb2b53cc9148ab1b1a [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __TESTS_MOCKDOCKER_HPP__
#define __TESTS_MOCKDOCKER_HPP__
#include <map>
#include <string>
#include <vector>
#include <gmock/gmock.h>
#include <mesos/resources.hpp>
#include <mesos/slave/container_logger.hpp>
#include <process/future.hpp>
#include <process/owned.hpp>
#include <process/shared.hpp>
#include <stout/json.hpp>
#include <stout/option.hpp>
#include "slave/containerizer/docker.hpp"
#include "slave/containerizer/mesos/isolators/gpu/components.hpp"
using ::testing::_;
using ::testing::Invoke;
using mesos::internal::slave::NvidiaComponents;
namespace mesos {
namespace internal {
namespace tests {
// Definition of a mock Docker to be used in tests with gmock.
class MockDocker : public Docker
{
public:
MockDocker(
const std::string& path,
const std::string& socket,
const Option<JSON::Object>& config = None());
~MockDocker() override;
MOCK_CONST_METHOD3(
run,
process::Future<Option<int>>(
const Docker::RunOptions& options,
const process::Subprocess::IO&,
const process::Subprocess::IO&));
MOCK_CONST_METHOD2(
ps,
process::Future<std::vector<Docker::Container>>(
bool, const Option<std::string>&));
MOCK_CONST_METHOD3(
pull,
process::Future<Docker::Image>(
const std::string&,
const std::string&,
bool));
MOCK_CONST_METHOD3(
stop,
process::Future<Nothing>(
const std::string&,
const Duration&,
bool));
MOCK_CONST_METHOD2(
inspect,
process::Future<Docker::Container>(
const std::string&,
const Option<Duration>&));
process::Future<Option<int>> _run(
const Docker::RunOptions& runOptions,
const process::Subprocess::IO& _stdout,
const process::Subprocess::IO& _stderr) const
{
return Docker::run(
runOptions,
_stdout,
_stderr);
}
process::Future<std::vector<Docker::Container>> _ps(
bool all,
const Option<std::string>& prefix) const
{
return Docker::ps(all, prefix);
}
process::Future<Docker::Image> _pull(
const std::string& directory,
const std::string& image,
bool force) const
{
return Docker::pull(directory, image, force);
}
process::Future<Nothing> _stop(
const std::string& containerName,
const Duration& timeout,
bool remove) const
{
return Docker::stop(containerName, timeout, remove);
}
process::Future<Docker::Container> _inspect(
const std::string& containerName,
const Option<Duration>& retryInterval)
{
return Docker::inspect(containerName, retryInterval);
}
};
// Definition of a mock DockerContainerizer to be used in tests with gmock.
class MockDockerContainerizer : public slave::DockerContainerizer {
public:
MockDockerContainerizer(
const slave::Flags& flags,
slave::Fetcher* fetcher,
const process::Owned<mesos::slave::ContainerLogger>& logger,
process::Shared<Docker> docker,
const Option<NvidiaComponents>& nvidia = None());
MockDockerContainerizer(
const process::Owned<slave::DockerContainerizerProcess>& process);
~MockDockerContainerizer() override;
void initialize()
{
// NOTE: See TestContainerizer::setup for why we use
// 'EXPECT_CALL' and 'WillRepeatedly' here instead of
// 'ON_CALL' and 'WillByDefault'.
EXPECT_CALL(*this, launch(_, _, _, _))
.WillRepeatedly(Invoke(this, &MockDockerContainerizer::_launch));
EXPECT_CALL(*this, update(_, _, _))
.WillRepeatedly(Invoke(this, &MockDockerContainerizer::_update));
}
MOCK_METHOD4(
launch,
process::Future<slave::Containerizer::LaunchResult>(
const ContainerID&,
const mesos::slave::ContainerConfig&,
const std::map<std::string, std::string>&,
const Option<std::string>&));
MOCK_METHOD3(
update,
process::Future<Nothing>(
const ContainerID&,
const Resources&,
const google::protobuf::Map<std::string, Value::Scalar>&));
// Default 'launch' implementation (necessary because we can't just
// use &slave::DockerContainerizer::launch with 'Invoke').
process::Future<slave::Containerizer::LaunchResult> _launch(
const ContainerID& containerId,
const mesos::slave::ContainerConfig& containerConfig,
const std::map<std::string, std::string>& environment,
const Option<std::string>& pidCheckpointPath)
{
return slave::DockerContainerizer::launch(
containerId,
containerConfig,
environment,
pidCheckpointPath);
}
process::Future<Nothing> _update(
const ContainerID& containerId,
const Resources& resourceRequests,
const google::protobuf::Map<std::string, Value::Scalar>& resourceLimits)
{
return slave::DockerContainerizer::update(
containerId,
resourceRequests,
resourceLimits);
}
};
// Definition of a mock DockerContainerizerProcess to be used in tests
// with gmock.
class MockDockerContainerizerProcess : public slave::DockerContainerizerProcess
{
public:
MockDockerContainerizerProcess(
const slave::Flags& flags,
slave::Fetcher* fetcher,
const process::Owned<mesos::slave::ContainerLogger>& logger,
const process::Shared<Docker>& docker,
const Option<NvidiaComponents>& nvidia = None());
~MockDockerContainerizerProcess() override;
MOCK_METHOD1(
fetch,
process::Future<Nothing>(const ContainerID&));
MOCK_METHOD1(
pull,
process::Future<Nothing>(const ContainerID&));
process::Future<Nothing> _fetch(const ContainerID& containerId)
{
return slave::DockerContainerizerProcess::fetch(containerId);
}
process::Future<Nothing> _pull(const ContainerID& containerId)
{
return slave::DockerContainerizerProcess::pull(containerId);
}
};
} // namespace tests {
} // namespace internal {
} // namespace mesos {
#endif // __TESTS_MOCKDOCKER_HPP__