Apache Mesos
mesos.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __TESTS_MESOS_HPP__
18 #define __TESTS_MESOS_HPP__
19 
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <gmock/gmock.h>
25 
26 #include <mesos/executor.hpp>
27 #include <mesos/scheduler.hpp>
28 
29 #include <mesos/v1/executor.hpp>
30 #include <mesos/v1/resources.hpp>
32 #include <mesos/v1/scheduler.hpp>
33 
35 
37 
39 
41 
43 
45 
46 #include <process/future.hpp>
47 #include <process/gmock.hpp>
48 #include <process/gtest.hpp>
49 #include <process/http.hpp>
50 #include <process/io.hpp>
51 #include <process/owned.hpp>
52 #include <process/pid.hpp>
53 #include <process/process.hpp>
54 #include <process/queue.hpp>
55 #include <process/subprocess.hpp>
56 
57 #include <process/ssl/flags.hpp>
58 #include <process/ssl/gtest.hpp>
59 
60 #include <stout/bytes.hpp>
61 #include <stout/foreach.hpp>
62 #include <stout/gtest.hpp>
63 #include <stout/lambda.hpp>
64 #include <stout/none.hpp>
65 #include <stout/option.hpp>
66 #include <stout/stringify.hpp>
67 #include <stout/try.hpp>
68 #include <stout/unreachable.hpp>
69 #include <stout/uuid.hpp>
70 
72 
73 #include "common/http.hpp"
74 
75 #include "messages/messages.hpp" // For google::protobuf::Message.
76 
77 #include "master/master.hpp"
78 
79 #include "sched/constants.hpp"
80 
82 
83 #include "slave/constants.hpp"
84 #include "slave/slave.hpp"
85 
87 
89 
90 #include "tests/cluster.hpp"
91 #include "tests/limiter.hpp"
92 #include "tests/utils.hpp"
93 
94 #ifdef MESOS_HAS_JAVA
95 #include "tests/zookeeper.hpp"
96 #endif // MESOS_HAS_JAVA
97 
98 using ::testing::_;
99 using ::testing::An;
100 using ::testing::DoDefault;
101 using ::testing::Invoke;
102 using ::testing::Return;
103 
104 namespace mesos {
105 namespace internal {
106 namespace tests {
107 
108 constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "test-readonly-realm";
109 constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "test-readwrite-realm";
110 constexpr char DEFAULT_TEST_ROLE[] = "default-role";
111 constexpr char DEFAULT_JWT_SECRET_KEY[] =
112  "72kUKUFtghAjNbIOvLzfF2RxNBfeM64Bri8g9WhpyaunwqRB/yozHAqSnyHbddAV"
113  "PcWRQlrJAt871oWgSH+n52vMZ3aVI+AFMzXSo8+sUfMk83IGp0WJefhzeQsjDlGH"
114  "GYQgCAuGim0BE2X5U+lEue8s697uQpAO8L/FFRuDH2s";
115 
116 
117 // Forward declarations.
118 class MockExecutor;
119 
120 
121 // NOTE: `SSLTemporaryDirectoryTest` exists even when SSL is not compiled into
122 // Mesos. In this case, the class is an alias of `TemporaryDirectoryTest`.
124 {
125 public:
126  static void SetUpTestCase();
127  static void TearDownTestCase();
128 
129 protected:
130  MesosTest(const Option<zookeeper::URL>& url = None());
131 
132  // Returns the flags used to create masters.
133  virtual master::Flags CreateMasterFlags();
134 
135  // Returns the flags used to create slaves.
136  virtual slave::Flags CreateSlaveFlags();
137 
138  // Starts a master with the specified flags.
140  const Option<master::Flags>& flags = None());
141 
142  // Starts a master with the specified allocator process and flags.
144  mesos::allocator::Allocator* allocator,
145  const Option<master::Flags>& flags = None());
146 
147  // Starts a master with the specified authorizer and flags.
149  Authorizer* authorizer,
150  const Option<master::Flags>& flags = None());
151 
152  // Starts a master with a slave removal rate limiter and flags.
153  // NOTE: The `slaveRemovalLimiter` is a `shared_ptr` because the
154  // underlying `Master` process requires the pointer in this form.
156  const std::shared_ptr<MockRateLimiter>& slaveRemovalLimiter,
157  const Option<master::Flags>& flags = None());
158 
159  // TODO(bmahler): Consider adding a builder style interface, e.g.
160  //
161  // Try<PID<Slave>> slave =
162  // Slave().With(flags)
163  // .With(executor)
164  // .With(containerizer)
165  // .With(detector)
166  // .With(gc)
167  // .Start();
168  //
169  // Or options:
170  //
171  // Injections injections;
172  // injections.executor = executor;
173  // injections.containerizer = containerizer;
174  // injections.detector = detector;
175  // injections.gc = gc;
176  // Try<PID<Slave>> slave = StartSlave(injections);
177 
178  // Starts a slave with the specified detector and flags.
181  const Option<slave::Flags>& flags = None(),
182  bool mock = false);
183 
184  // Starts a slave with the specified detector, containerizer, and flags.
187  slave::Containerizer* containerizer,
188  const Option<slave::Flags>& flags = None(),
189  bool mock = false);
190 
191  // Starts a slave with the specified detector, id, and flags.
194  const std::string& id,
195  const Option<slave::Flags>& flags = None(),
196  bool mock = false);
197 
198  // Starts a slave with the specified detector, containerizer, id, and flags.
201  slave::Containerizer* containerizer,
202  const std::string& id,
203  const Option<slave::Flags>& flags = None());
204 
205  // Starts a slave with the specified detector, GC, and flags.
209  const Option<slave::Flags>& flags = None(),
210  bool mock = false);
211 
212  // Starts a slave with the specified detector, resource estimator, and flags.
215  mesos::slave::ResourceEstimator* resourceEstimator,
216  const Option<slave::Flags>& flags = None());
217 
218  // Starts a slave with the specified detector, containerizer,
219  // resource estimator, and flags.
222  slave::Containerizer* containerizer,
223  mesos::slave::ResourceEstimator* resourceEstimator,
224  const Option<slave::Flags>& flags = None());
225 
226  // Starts a slave with the specified detector, QoS Controller, and flags.
229  mesos::slave::QoSController* qosController,
230  const Option<slave::Flags>& flags = None());
231 
232  // Starts a slave with the specified detector, containerizer,
233  // QoS Controller, and flags.
236  slave::Containerizer* containerizer,
237  mesos::slave::QoSController* qosController,
238  const Option<slave::Flags>& flags = None(),
239  bool mock = false);
240 
241  // Starts a slave with the specified detector, authorizer, and flags.
244  mesos::Authorizer* authorizer,
245  const Option<slave::Flags>& flags = None(),
246  bool mock = false);
247 
248  // Starts a slave with the specified detector, containerizer, authorizer,
249  // and flags.
252  slave::Containerizer* containerizer,
253  mesos::Authorizer* authorizer,
254  const Option<slave::Flags>& flags = None(),
255  bool mock = false);
256 
257  // Starts a slave with the specified detector, containerizer,
258  // secretGenerator, authorizer and flags.
261  slave::Containerizer* containerizer,
262  mesos::SecretGenerator* secretGenerator,
263  const Option<mesos::Authorizer*>& authorizer = None(),
264  const Option<slave::Flags>& flags = None(),
265  bool mock = false);
266 
267  // Starts a slave with the specified detector, secretGenerator,
268  // and flags.
271  mesos::SecretGenerator* secretGenerator,
272  const Option<slave::Flags>& flags = None());
273 
275 
276  // NOTE: On Windows, most tasks are run under PowerShell, which uses ~150 MB
277  // of memory per-instance due to loading .NET. Realistically, PowerShell can
278  // be called more than once in a task, so 512 MB is the safe minimum.
279  // Furthermore, because the Windows `cpu` isolator is a hard-cap, 0.1 CPUs
280  // will cause the task (or even a check command) to timeout, so 1 CPU is the
281  // safe minimum.
282  //
283  // Because multiple tasks can be run, the default agent resources needs to be
284  // at least a multiple of the default task resources: four times seems safe.
285  //
286  // On platforms where the shell is, e.g. Bash, the minimum is much lower.
287  const std::string defaultAgentResourcesString{
288 #ifdef __WINDOWS__
289  "cpus:4;gpus:0;mem:2048;disk:1024;ports:[31000-32000]"
290 #else
291  "cpus:2;gpus:0;mem:1024;disk:1024;ports:[31000-32000]"
292 #endif // __WINDOWS__
293  };
294 
295  const std::string defaultTaskResourcesString{
296 #ifdef __WINDOWS__
297  "cpus:1;mem:512;disk:32"
298 #else
299  "cpus:0.1;mem:32;disk:32"
300 #endif // __WINDOWS__
301  };
302 };
303 
304 
305 template <typename T>
306 class ContainerizerTest : public MesosTest {};
307 
308 #ifdef __linux__
309 // Cgroups hierarchy used by the cgroups related tests.
310 const static std::string TEST_CGROUPS_HIERARCHY = "/tmp/mesos_test_cgroup";
311 
312 // Name of the root cgroup used by the cgroups related tests.
313 const static std::string TEST_CGROUPS_ROOT = "mesos_test";
314 
315 
316 template <>
317 class ContainerizerTest<slave::MesosContainerizer> : public MesosTest
318 {
319 public:
320  static void SetUpTestCase();
321  static void TearDownTestCase();
322 
323 protected:
324  slave::Flags CreateSlaveFlags() override;
325  void SetUp() override;
326  void TearDown() override;
327 
328 private:
329  // Base hierarchy for separately mounted cgroup controllers, e.g., if the
330  // base hierarchy is /sys/fs/cgroup then each controller will be mounted to
331  // /sys/fs/cgroup/{controller}/.
332  std::string baseHierarchy;
333 
334  // Set of cgroup subsystems used by the cgroups related tests.
336 };
337 #else
338 template <>
339 class ContainerizerTest<slave::MesosContainerizer> : public MesosTest
340 {
341 protected:
342  virtual slave::Flags CreateSlaveFlags();
343 };
344 #endif // __linux__
345 
346 
347 #ifdef MESOS_HAS_JAVA
348 
349 class MesosZooKeeperTest : public MesosTest
350 {
351 public:
352  static void SetUpTestCase()
353  {
354  // Make sure the JVM is created.
356 
357  // Launch the ZooKeeper test server.
358  server = new ZooKeeperTestServer();
359  server->startNetwork();
360 
362  "zk://" + server->connectString() + "/znode");
363  ASSERT_SOME(parse);
364 
365  url = parse.get();
366  }
367 
368  static void TearDownTestCase()
369  {
370  delete server;
371  server = nullptr;
372  }
373 
374  void SetUp() override
375  {
377  server->startNetwork();
378  }
379 
380  void TearDown() override
381  {
382  server->shutdownNetwork();
384  }
385 
386 protected:
387  MesosZooKeeperTest() : MesosTest(url) {}
388 
389  master::Flags CreateMasterFlags() override
390  {
391  master::Flags flags = MesosTest::CreateMasterFlags();
392 
393  // NOTE: Since we are using the replicated log with ZooKeeper
394  // (default storage in MesosTest), we need to specify the quorum.
395  flags.quorum = 1;
396 
397  return flags;
398  }
399 
400  static ZooKeeperTestServer* server;
401  static Option<zookeeper::URL> url;
402 };
403 
404 #endif // MESOS_HAS_JAVA
405 
406 namespace v1 {
407 
408 // Alias existing `mesos::v1` namespaces so that we can easily write
409 // `v1::` in tests.
410 //
411 // TODO(jmlvanre): Remove these aliases once we clean up the `tests`
412 // namespace hierarchy.
413 namespace agent = mesos::v1::agent;
414 namespace maintenance = mesos::v1::maintenance;
415 namespace master = mesos::v1::master;
416 namespace quota = mesos::v1::quota;
417 
418 using mesos::v1::OPERATION_PENDING;
419 using mesos::v1::OPERATION_FINISHED;
420 using mesos::v1::OPERATION_FAILED;
421 using mesos::v1::OPERATION_ERROR;
422 using mesos::v1::OPERATION_DROPPED;
423 using mesos::v1::OPERATION_UNREACHABLE;
424 using mesos::v1::OPERATION_GONE_BY_OPERATOR;
425 using mesos::v1::OPERATION_RECOVERING;
426 using mesos::v1::OPERATION_UNKNOWN;
427 
428 using mesos::v1::TASK_STAGING;
429 using mesos::v1::TASK_STARTING;
430 using mesos::v1::TASK_RUNNING;
431 using mesos::v1::TASK_KILLING;
432 using mesos::v1::TASK_FINISHED;
433 using mesos::v1::TASK_FAILED;
434 using mesos::v1::TASK_KILLED;
435 using mesos::v1::TASK_ERROR;
436 using mesos::v1::TASK_LOST;
437 using mesos::v1::TASK_DROPPED;
438 using mesos::v1::TASK_UNREACHABLE;
439 using mesos::v1::TASK_GONE;
440 using mesos::v1::TASK_GONE_BY_OPERATOR;
441 using mesos::v1::TASK_UNKNOWN;
442 
443 using mesos::v1::AgentID;
444 using mesos::v1::CheckInfo;
445 using mesos::v1::CommandInfo;
446 using mesos::v1::ContainerID;
447 using mesos::v1::ContainerStatus;
448 using mesos::v1::Environment;
449 using mesos::v1::ExecutorID;
450 using mesos::v1::ExecutorInfo;
451 using mesos::v1::Filters;
452 using mesos::v1::FrameworkID;
453 using mesos::v1::FrameworkInfo;
454 using mesos::v1::HealthCheck;
455 using mesos::v1::InverseOffer;
456 using mesos::v1::MachineID;
457 using mesos::v1::Metric;
458 using mesos::v1::Offer;
459 using mesos::v1::OperationID;
460 using mesos::v1::OperationState;
461 using mesos::v1::OperationStatus;
462 using mesos::v1::Resource;
463 using mesos::v1::ResourceProviderID;
464 using mesos::v1::ResourceProviderInfo;
466 using mesos::v1::TaskID;
467 using mesos::v1::TaskInfo;
468 using mesos::v1::TaskGroupInfo;
469 using mesos::v1::TaskState;
470 using mesos::v1::TaskStatus;
471 using mesos::v1::UUID;
472 using mesos::v1::WeightInfo;
473 
474 } // namespace v1 {
475 
476 namespace common {
477 
478 template <typename TCredential>
480 {
481  static TCredential create()
482  {
483  TCredential credential;
484  credential.set_principal("test-principal");
485  credential.set_secret("test-secret");
486  return credential;
487  }
488 };
489 
490 
491 // TODO(jmlvanre): consider factoring this out.
492 template <typename TCredential>
494 {
495  static TCredential create()
496  {
497  TCredential credential;
498  credential.set_principal("test-principal-2");
499  credential.set_secret("test-secret-2");
500  return credential;
501  }
502 };
503 
504 
505 template <typename TFrameworkInfo, typename TCredential>
507 {
508  static TFrameworkInfo create()
509  {
510  TFrameworkInfo framework;
511  framework.set_name("default");
512  framework.set_user(os::user().get());
513  framework.set_principal(
515  framework.add_roles("*");
516  framework.add_capabilities()->set_type(
517  TFrameworkInfo::Capability::MULTI_ROLE);
518  framework.add_capabilities()->set_type(
519  TFrameworkInfo::Capability::RESERVATION_REFINEMENT);
520 
521  return framework;
522  }
523 };
524 
525 } // namespace common {
526 
527 // TODO(jmlvanre): Remove `inline` once we have adjusted all tests to
528 // distinguish between `internal` and `v1`.
529 inline namespace internal {
532 using DefaultFrameworkInfo =
534 } // namespace internal {
535 
536 
537 namespace v1 {
540 using DefaultFrameworkInfo =
542 } // namespace v1 {
543 
544 
545 // We factor out all common behavior and templatize it so that we can
546 // can call it from both `v1::` and `internal::`.
547 namespace common {
548 
549 template <typename TCommandInfo>
550 inline TCommandInfo createCommandInfo(
551  const Option<std::string>& value = None(),
552  const std::vector<std::string>& arguments = {})
553 {
554  TCommandInfo commandInfo;
555  if (value.isSome()) {
556  commandInfo.set_value(value.get());
557  }
558  if (!arguments.empty()) {
559  commandInfo.set_shell(false);
560  foreach (const std::string& arg, arguments) {
561  commandInfo.add_arguments(arg);
562  }
563  }
564  return commandInfo;
565 }
566 
567 
568 template <typename TExecutorInfo,
569  typename TExecutorID,
570  typename TResources,
571  typename TCommandInfo,
572  typename TFrameworkID>
573 inline TExecutorInfo createExecutorInfo(
574  const TExecutorID& executorId,
575  const Option<TCommandInfo>& command,
576  const Option<TResources>& resources,
578  const Option<TFrameworkID>& frameworkId)
579 {
580  TExecutorInfo executor;
581  executor.mutable_executor_id()->CopyFrom(executorId);
582  if (command.isSome()) {
583  executor.mutable_command()->CopyFrom(command.get());
584  }
585  if (resources.isSome()) {
586  executor.mutable_resources()->CopyFrom(resources.get());
587  }
588  if (type.isSome()) {
589  executor.set_type(type.get());
590  }
591  if (frameworkId.isSome()) {
592  executor.mutable_framework_id()->CopyFrom(frameworkId.get());
593  }
594  return executor;
595 }
596 
597 
598 template <typename TExecutorInfo,
599  typename TExecutorID,
600  typename TResources,
601  typename TCommandInfo,
602  typename TFrameworkID>
603 inline TExecutorInfo createExecutorInfo(
604  const std::string& _executorId,
605  const Option<TCommandInfo>& command,
606  const Option<TResources>& resources,
608  const Option<TFrameworkID>& frameworkId)
609 {
610  TExecutorID executorId;
611  executorId.set_value(_executorId);
612  return createExecutorInfo<TExecutorInfo,
613  TExecutorID,
614  TResources,
615  TCommandInfo,
616  TFrameworkID>(
617  executorId, command, resources, type, frameworkId);
618 }
619 
620 
621 template <typename TExecutorInfo,
622  typename TExecutorID,
623  typename TResources,
624  typename TCommandInfo,
625  typename TFrameworkID>
626 inline TExecutorInfo createExecutorInfo(
627  const std::string& executorId,
628  const Option<TCommandInfo>& command = None(),
629  const Option<std::string>& resources = None(),
631  const Option<TFrameworkID>& frameworkId = None())
632 {
633  if (resources.isSome()) {
634  return createExecutorInfo<TExecutorInfo,
635  TExecutorID,
636  TResources,
637  TCommandInfo,
638  TFrameworkID>(
639  executorId,
640  command,
641  TResources::parse(resources.get()).get(),
642  type,
643  frameworkId);
644  }
645 
646  return createExecutorInfo<TExecutorInfo,
647  TExecutorID,
648  TResources,
649  TCommandInfo,
650  TFrameworkID>(
651  executorId, command, Option<TResources>::none(), type, frameworkId);
652 }
653 
654 
655 template <typename TExecutorInfo,
656  typename TExecutorID,
657  typename TResources,
658  typename TCommandInfo,
659  typename TFrameworkID>
660 inline TExecutorInfo createExecutorInfo(
661  const TExecutorID& executorId,
662  const Option<TCommandInfo>& command,
663  const std::string& resources,
665  const Option<TFrameworkID>& frameworkId = None())
666 {
667  return createExecutorInfo<TExecutorInfo,
668  TExecutorID,
669  TResources,
670  TCommandInfo,
671  TFrameworkID>(
672  executorId,
673  command,
674  TResources::parse(resources).get(),
675  type,
676  frameworkId);
677 }
678 
679 
680 template <typename TExecutorInfo,
681  typename TExecutorID,
682  typename TResources,
683  typename TCommandInfo,
684  typename TFrameworkID>
685 inline TExecutorInfo createExecutorInfo(
686  const std::string& executorId,
687  const std::string& command,
688  const Option<std::string>& resources = None(),
690  const Option<TFrameworkID>& frameworkId = None())
691 {
692  TCommandInfo commandInfo = createCommandInfo<TCommandInfo>(command);
693  return createExecutorInfo<TExecutorInfo,
694  TExecutorID,
695  TResources,
696  TCommandInfo,
697  TFrameworkID>(
698  executorId, commandInfo, resources, type, frameworkId);
699 }
700 
701 
702 template <typename TImage>
703 inline TImage createDockerImage(const std::string& imageName)
704 {
705  TImage image;
706  image.set_type(TImage::DOCKER);
707  image.mutable_docker()->set_name(imageName);
708  return image;
709 }
710 
711 
712 template <typename TVolume>
713 inline TVolume createVolumeSandboxPath(
714  const std::string& containerPath,
715  const std::string& sandboxPath,
716  const typename TVolume::Mode& mode)
717 {
718  TVolume volume;
719  volume.set_container_path(containerPath);
720  volume.set_mode(mode);
721 
722  // TODO(jieyu): Use TVolume::Source::SANDBOX_PATH.
723  volume.set_host_path(sandboxPath);
724 
725  return volume;
726 }
727 
728 
729 template <typename TVolume, typename TMountPropagation>
730 inline TVolume createVolumeHostPath(
731  const std::string& containerPath,
732  const std::string& hostPath,
733  const typename TVolume::Mode& mode,
734  const Option<typename TMountPropagation::Mode>& mountPropagationMode =
735  None())
736 {
737  TVolume volume;
738  volume.set_container_path(containerPath);
739  volume.set_mode(mode);
740 
741  typename TVolume::Source* source = volume.mutable_source();
742  source->set_type(TVolume::Source::HOST_PATH);
743  source->mutable_host_path()->set_path(hostPath);
744 
745  if (mountPropagationMode.isSome()) {
746  source
747  ->mutable_host_path()
748  ->mutable_mount_propagation()
749  ->set_mode(mountPropagationMode.get());
750  }
751 
752  return volume;
753 }
754 
755 
756 template <typename TVolume, typename TImage>
758  const std::string& containerPath,
759  const std::string& imageName,
760  const typename TVolume::Mode& mode)
761 {
762  TVolume volume;
763  volume.set_container_path(containerPath);
764  volume.set_mode(mode);
765  volume.mutable_image()->CopyFrom(createDockerImage<TImage>(imageName));
766  return volume;
767 }
768 
769 
770 template <typename TNetworkInfo>
771 inline TNetworkInfo createNetworkInfo(
772  const std::string& networkName)
773 {
774  TNetworkInfo info;
775  info.set_name(networkName);
776  return info;
777 }
778 
779 
780 template <typename TContainerInfo, typename TVolume, typename TImage>
781 inline TContainerInfo createContainerInfo(
782  const Option<std::string>& imageName = None(),
783  const std::vector<TVolume>& volumes = {})
784 {
785  TContainerInfo info;
786  info.set_type(TContainerInfo::MESOS);
787 
788  if (imageName.isSome()) {
789  TImage* image = info.mutable_mesos()->mutable_image();
790  image->CopyFrom(createDockerImage<TImage>(imageName.get()));
791  }
792 
793  foreach (const TVolume& volume, volumes) {
794  info.add_volumes()->CopyFrom(volume);
795  }
796 
797  return info;
798 }
799 
800 
801 inline SlaveID getAgentID(const Offer& offer)
802 {
803  return offer.slave_id();
804 }
805 
806 
807 inline mesos::v1::AgentID getAgentID(const mesos::v1::Offer& offer)
808 {
809  return offer.agent_id();
810 }
811 
812 
813 inline void setAgentID(TaskInfo* task, const SlaveID& slaveId)
814 {
815  task->mutable_slave_id()->CopyFrom(slaveId);
816 }
817 
818 
819 inline void setAgentID(
820  mesos::v1::TaskInfo* task,
821  const mesos::v1::AgentID& agentId)
822 {
823  task->mutable_agent_id()->CopyFrom(agentId);
824 }
825 
826 
827 // TODO(bmahler): Refactor this to make the distinction between
828 // command tasks and executor tasks clearer.
829 template <
830  typename TTaskInfo,
831  typename TExecutorID,
832  typename TSlaveID,
833  typename TResources,
834  typename TExecutorInfo,
835  typename TCommandInfo,
836  typename TOffer>
837 inline TTaskInfo createTask(
838  const TSlaveID& slaveId,
839  const TResources& resources,
840  const TCommandInfo& command,
841  const Option<TExecutorID>& executorId = None(),
842  const std::string& name = "test-task",
843  const std::string& id = id::UUID::random().toString())
844 {
845  TTaskInfo task;
846  task.set_name(name);
847  task.mutable_task_id()->set_value(id);
848  setAgentID(&task, slaveId);
849  task.mutable_resources()->CopyFrom(resources);
850  if (executorId.isSome()) {
851  TExecutorInfo executor;
852  executor.mutable_executor_id()->CopyFrom(executorId.get());
853  executor.mutable_command()->CopyFrom(command);
854  task.mutable_executor()->CopyFrom(executor);
855  } else {
856  task.mutable_command()->CopyFrom(command);
857  }
858 
859  return task;
860 }
861 
862 
863 template <
864  typename TTaskInfo,
865  typename TExecutorID,
866  typename TSlaveID,
867  typename TResources,
868  typename TExecutorInfo,
869  typename TCommandInfo,
870  typename TOffer>
871 inline TTaskInfo createTask(
872  const TSlaveID& slaveId,
873  const TResources& resources,
874  const std::string& command,
875  const Option<TExecutorID>& executorId = None(),
876  const std::string& name = "test-task",
877  const std::string& id = id::UUID::random().toString())
878 {
879  return createTask<
880  TTaskInfo,
881  TExecutorID,
882  TSlaveID,
883  TResources,
884  TExecutorInfo,
885  TCommandInfo,
886  TOffer>(
887  slaveId,
888  resources,
889  createCommandInfo<TCommandInfo>(command),
890  executorId,
891  name,
892  id);
893 }
894 
895 
896 template <
897  typename TTaskInfo,
898  typename TExecutorID,
899  typename TSlaveID,
900  typename TResources,
901  typename TExecutorInfo,
902  typename TCommandInfo,
903  typename TOffer>
904 inline TTaskInfo createTask(
905  const TOffer& offer,
906  const std::string& command,
907  const Option<TExecutorID>& executorId = None(),
908  const std::string& name = "test-task",
909  const std::string& id = id::UUID::random().toString())
910 {
911  return createTask<
912  TTaskInfo,
913  TExecutorID,
914  TSlaveID,
915  TResources,
916  TExecutorInfo,
917  TCommandInfo,
918  TOffer>(
919  getAgentID(offer),
920  offer.resources(),
921  command,
922  executorId,
923  name,
924  id);
925 }
926 
927 
928 template <typename TTaskGroupInfo, typename TTaskInfo>
929 inline TTaskGroupInfo createTaskGroupInfo(const std::vector<TTaskInfo>& tasks)
930 {
931  TTaskGroupInfo taskGroup;
932  foreach (const TTaskInfo& task, tasks) {
933  taskGroup.add_tasks()->CopyFrom(task);
934  }
935  return taskGroup;
936 }
937 
938 
939 template <typename TResource>
940 inline typename TResource::ReservationInfo createStaticReservationInfo(
941  const std::string& role)
942 {
943  typename TResource::ReservationInfo info;
944  info.set_type(TResource::ReservationInfo::STATIC);
945  info.set_role(role);
946  return info;
947 }
948 
949 
950 template <typename TResource, typename TLabels>
951 inline typename TResource::ReservationInfo createDynamicReservationInfo(
952  const std::string& role,
953  const Option<std::string>& principal = None(),
954  const Option<TLabels>& labels = None())
955 {
956  typename TResource::ReservationInfo info;
957 
958  info.set_type(TResource::ReservationInfo::DYNAMIC);
959  info.set_role(role);
960 
961  if (principal.isSome()) {
962  info.set_principal(principal.get());
963  }
964 
965  if (labels.isSome()) {
966  info.mutable_labels()->CopyFrom(labels.get());
967  }
968 
969  return info;
970 }
971 
972 
973 template <
974  typename TResource,
975  typename TResources,
976  typename... TReservationInfos>
977 inline TResource createReservedResource(
978  const std::string& name,
979  const std::string& value,
980  const TReservationInfos&... reservations)
981 {
982  std::initializer_list<typename TResource::ReservationInfo> reservations_ = {
983  reservations...
984  };
985 
986  TResource resource = TResources::parse(name, value, "*").get();
987  resource.mutable_reservations()->CopyFrom(
988  google::protobuf::RepeatedPtrField<typename TResource::ReservationInfo>{
989  reservations_.begin(), reservations_.end()});
990 
991  return resource;
992 }
993 
994 
995 // NOTE: We only set the volume in DiskInfo if 'containerPath' is set.
996 // If volume mode is not specified, Volume::RW will be used (assuming
997 // 'containerPath' is set).
998 template <typename TResource, typename TVolume>
999 inline typename TResource::DiskInfo createDiskInfo(
1000  const Option<std::string>& persistenceId,
1001  const Option<std::string>& containerPath,
1002  const Option<typename TVolume::Mode>& mode = None(),
1003  const Option<std::string>& hostPath = None(),
1005  const Option<std::string>& principal = None())
1006 {
1007  typename TResource::DiskInfo info;
1008 
1009  if (persistenceId.isSome()) {
1010  info.mutable_persistence()->set_id(persistenceId.get());
1011  }
1012 
1013  if (principal.isSome()) {
1014  info.mutable_persistence()->set_principal(principal.get());
1015  }
1016 
1017  if (containerPath.isSome()) {
1018  TVolume volume;
1019  volume.set_container_path(containerPath.get());
1020  volume.set_mode(mode.isSome() ? mode.get() : TVolume::RW);
1021 
1022  if (hostPath.isSome()) {
1023  volume.set_host_path(hostPath.get());
1024  }
1025 
1026  info.mutable_volume()->CopyFrom(volume);
1027  }
1028 
1029  if (source.isSome()) {
1030  info.mutable_source()->CopyFrom(source.get());
1031  }
1032 
1033  return info;
1034 }
1035 
1036 
1037 // Helper for creating a disk source with type `PATH`.
1038 template <typename TResource>
1039 inline typename TResource::DiskInfo::Source createDiskSourcePath(
1040  const Option<std::string>& root = None(),
1041  const Option<std::string>& id = None(),
1042  const Option<std::string>& profile = None())
1043 {
1044  typename TResource::DiskInfo::Source source;
1045 
1046  source.set_type(TResource::DiskInfo::Source::PATH);
1047 
1048  if (root.isSome()) {
1049  source.mutable_path()->set_root(root.get());
1050  }
1051 
1052  if (id.isSome()) {
1053  source.set_id(id.get());
1054  }
1055 
1056  if (profile.isSome()) {
1057  source.set_profile(profile.get());
1058  }
1059 
1060  return source;
1061 }
1062 
1063 
1064 // Helper for creating a disk source with type `MOUNT`.
1065 template <typename TResource>
1066 inline typename TResource::DiskInfo::Source createDiskSourceMount(
1067  const Option<std::string>& root = None(),
1068  const Option<std::string>& id = None(),
1069  const Option<std::string>& profile = None())
1070 {
1071  typename TResource::DiskInfo::Source source;
1072 
1073  source.set_type(TResource::DiskInfo::Source::MOUNT);
1074 
1075  if (root.isSome()) {
1076  source.mutable_mount()->set_root(root.get());
1077  }
1078 
1079  if (id.isSome()) {
1080  source.set_id(id.get());
1081  }
1082 
1083  if (profile.isSome()) {
1084  source.set_profile(profile.get());
1085  }
1086 
1087  return source;
1088 }
1089 
1090 
1091 // Helper for creating a disk source with type `BLOCK'
1092 template <typename TResource>
1093 inline typename TResource::DiskInfo::Source createDiskSourceBlock(
1094  const Option<std::string>& id = None(),
1095  const Option<std::string>& profile = None())
1096 {
1097  typename TResource::DiskInfo::Source source;
1098 
1099  source.set_type(TResource::DiskInfo::Source::BLOCK);
1100 
1101  if (id.isSome()) {
1102  source.set_id(id.get());
1103  }
1104 
1105  if (profile.isSome()) {
1106  source.set_profile(profile.get());
1107  }
1108 
1109  return source;
1110 }
1111 
1112 
1113 // Helper for creating a disk source with type `RAW'.
1114 template <typename TResource>
1115 inline typename TResource::DiskInfo::Source createDiskSourceRaw(
1116  const Option<std::string>& id = None(),
1117  const Option<std::string>& profile = None())
1118 {
1119  typename TResource::DiskInfo::Source source;
1120 
1121  source.set_type(TResource::DiskInfo::Source::RAW);
1122 
1123  if (id.isSome()) {
1124  source.set_id(id.get());
1125  }
1126 
1127  if (profile.isSome()) {
1128  source.set_profile(profile.get());
1129  }
1130 
1131  return source;
1132 }
1133 
1134 
1135 // Helper for creating a disk resource.
1136 template <typename TResource, typename TResources, typename TVolume>
1137 inline TResource createDiskResource(
1138  const std::string& value,
1139  const std::string& role,
1140  const Option<std::string>& persistenceID,
1141  const Option<std::string>& containerPath,
1143  bool isShared = false)
1144 {
1145  TResource resource = TResources::parse("disk", value, role).get();
1146 
1147  if (persistenceID.isSome() || containerPath.isSome() || source.isSome()) {
1148  resource.mutable_disk()->CopyFrom(
1149  createDiskInfo<TResource, TVolume>(
1150  persistenceID,
1151  containerPath,
1152  None(),
1153  None(),
1154  source));
1155 
1156  if (isShared) {
1157  resource.mutable_shared();
1158  }
1159  }
1160 
1161  return resource;
1162 }
1163 
1164 
1165 // Note that `reservationPrincipal` should be specified if and only if
1166 // the volume uses dynamically reserved resources.
1167 template <typename TResource, typename TResources, typename TVolume>
1168 inline TResource createPersistentVolume(
1169  const Bytes& size,
1170  const std::string& role,
1171  const std::string& persistenceId,
1172  const std::string& containerPath,
1173  const Option<std::string>& reservationPrincipal = None(),
1175  const Option<std::string>& creatorPrincipal = None(),
1176  bool isShared = false)
1177 {
1178  TResource volume = TResources::parse(
1179  "disk",
1180  stringify((double) size.bytes() / Bytes::MEGABYTES),
1181  role).get();
1182 
1183  volume.mutable_disk()->CopyFrom(
1184  createDiskInfo<TResource, TVolume>(
1185  persistenceId,
1186  containerPath,
1187  None(),
1188  None(),
1189  source,
1190  creatorPrincipal));
1191 
1192  if (reservationPrincipal.isSome()) {
1193  typename TResource::ReservationInfo& reservation =
1194  *volume.mutable_reservations()->rbegin();
1195 
1196  reservation.set_type(TResource::ReservationInfo::DYNAMIC);
1197  reservation.set_principal(reservationPrincipal.get());
1198  }
1199 
1200  if (isShared) {
1201  volume.mutable_shared();
1202  }
1203 
1204  return volume;
1205 }
1206 
1207 
1208 // Note that `reservationPrincipal` should be specified if and only if
1209 // the volume uses dynamically reserved resources.
1210 template <typename TResource, typename TResources, typename TVolume>
1211 inline TResource createPersistentVolume(
1212  TResource volume,
1213  const std::string& persistenceId,
1214  const std::string& containerPath,
1215  const Option<std::string>& reservationPrincipal = None(),
1216  const Option<std::string>& creatorPrincipal = None(),
1217  bool isShared = false)
1218 {
1220  if (volume.has_disk() && volume.disk().has_source()) {
1221  source = volume.disk().source();
1222  }
1223 
1224  volume.mutable_disk()->CopyFrom(
1225  createDiskInfo<TResource, TVolume>(
1226  persistenceId,
1227  containerPath,
1228  None(),
1229  None(),
1230  source,
1231  creatorPrincipal));
1232 
1233  if (reservationPrincipal.isSome()) {
1234  typename TResource::ReservationInfo& reservation =
1235  *volume.mutable_reservations()->rbegin();
1236 
1237  reservation.set_type(TResource::ReservationInfo::DYNAMIC);
1238  reservation.set_principal(reservationPrincipal.get());
1239  }
1240 
1241  if (isShared) {
1242  volume.mutable_shared();
1243  }
1244 
1245  return volume;
1246 }
1247 
1248 
1249 template <typename TCredential>
1251  const TCredential& credential)
1252 {
1253  return process::http::Headers({{
1254  "Authorization",
1255  "Basic " +
1256  base64::encode(credential.principal() + ":" + credential.secret())
1257  }});
1258 }
1259 
1260 
1261 // Create WeightInfos from the specified weights flag.
1262 template <typename TWeightInfo>
1263 inline google::protobuf::RepeatedPtrField<TWeightInfo> createWeightInfos(
1264  const std::string& weightsFlag)
1265 {
1266  google::protobuf::RepeatedPtrField<TWeightInfo> infos;
1267  std::vector<std::string> tokens = strings::tokenize(weightsFlag, ",");
1268  foreach (const std::string& token, tokens) {
1269  std::vector<std::string> pair = strings::tokenize(token, "=");
1270  EXPECT_EQ(2u, pair.size());
1271  double weight = atof(pair[1].c_str());
1272  TWeightInfo weightInfo;
1273  weightInfo.set_role(pair[0]);
1274  weightInfo.set_weight(weight);
1275  infos.Add()->CopyFrom(weightInfo);
1276  }
1277 
1278  return infos;
1279 }
1280 
1281 
1282 // Convert WeightInfos protobuf to weights hashmap.
1283 template <typename TWeightInfo>
1285  const google::protobuf::RepeatedPtrField<TWeightInfo> weightInfos)
1286 {
1288 
1289  foreach (const TWeightInfo& weightInfo, weightInfos) {
1290  weights[weightInfo.role()] = weightInfo.weight();
1291  }
1292 
1293  return weights;
1294 }
1295 
1296 
1297 // Helper to create DomainInfo.
1298 template <typename TDomainInfo>
1299 inline TDomainInfo createDomainInfo(
1300  const std::string& regionName,
1301  const std::string& zoneName)
1302 {
1303  TDomainInfo domain;
1304 
1305  domain.mutable_fault_domain()->mutable_region()->set_name(regionName);
1306  domain.mutable_fault_domain()->mutable_zone()->set_name(zoneName);
1307 
1308  return domain;
1309 }
1310 
1311 
1312 // Helpers for creating operations.
1313 template <typename TResources, typename TOperationID, typename TOffer>
1314 inline typename TOffer::Operation RESERVE(
1315  const TResources& resources,
1316  const Option<TOperationID>& operationId = None())
1317 {
1318  typename TOffer::Operation operation;
1319  operation.set_type(TOffer::Operation::RESERVE);
1320  operation.mutable_reserve()->mutable_resources()->CopyFrom(resources);
1321 
1322  if (operationId.isSome()) {
1323  operation.mutable_id()->CopyFrom(operationId.get());
1324  }
1325 
1326  return operation;
1327 }
1328 
1329 
1330 template <typename TResources, typename TOffer>
1331 inline typename TOffer::Operation UNRESERVE(const TResources& resources)
1332 {
1333  typename TOffer::Operation operation;
1334  operation.set_type(TOffer::Operation::UNRESERVE);
1335  operation.mutable_unreserve()->mutable_resources()->CopyFrom(resources);
1336  return operation;
1337 }
1338 
1339 
1340 template <typename TResources, typename TOffer>
1341 inline typename TOffer::Operation CREATE(const TResources& volumes)
1342 {
1343  typename TOffer::Operation operation;
1344  operation.set_type(TOffer::Operation::CREATE);
1345  operation.mutable_create()->mutable_volumes()->CopyFrom(volumes);
1346  return operation;
1347 }
1348 
1349 
1350 template <typename TResources, typename TOffer>
1351 inline typename TOffer::Operation DESTROY(const TResources& volumes)
1352 {
1353  typename TOffer::Operation operation;
1354  operation.set_type(TOffer::Operation::DESTROY);
1355  operation.mutable_destroy()->mutable_volumes()->CopyFrom(volumes);
1356  return operation;
1357 }
1358 
1359 
1360 template <typename TResource, typename TOffer>
1362  const TResource& volume,
1363  const TResource& addition)
1364 {
1365  typename TOffer::Operation operation;
1366  operation.set_type(TOffer::Operation::GROW_VOLUME);
1367  operation.mutable_grow_volume()->mutable_volume()->CopyFrom(volume);
1368  operation.mutable_grow_volume()->mutable_addition()->CopyFrom(addition);
1369  return operation;
1370 }
1371 
1372 
1373 template <typename TResource, typename TOffer, typename TValueScalar>
1375  const TResource& volume,
1376  const TValueScalar& subtract)
1377 {
1378  typename TOffer::Operation operation;
1379  operation.set_type(TOffer::Operation::SHRINK_VOLUME);
1380  operation.mutable_shrink_volume()->mutable_volume()->CopyFrom(volume);
1381  operation.mutable_shrink_volume()->mutable_subtract()->CopyFrom(subtract);
1382  return operation;
1383 }
1384 
1385 
1386 template <typename TOffer, typename TTaskInfo>
1387 inline typename TOffer::Operation LAUNCH(const std::vector<TTaskInfo>& tasks)
1388 {
1389  typename TOffer::Operation operation;
1390  operation.set_type(TOffer::Operation::LAUNCH);
1391 
1392  foreach (const TTaskInfo& task, tasks) {
1393  operation.mutable_launch()->add_task_infos()->CopyFrom(task);
1394  }
1395 
1396  return operation;
1397 }
1398 
1399 
1400 template <typename TExecutorInfo, typename TTaskGroupInfo, typename TOffer>
1402  const TExecutorInfo& executorInfo,
1403  const TTaskGroupInfo& taskGroup)
1404 {
1405  typename TOffer::Operation operation;
1406  operation.set_type(TOffer::Operation::LAUNCH_GROUP);
1407  operation.mutable_launch_group()->mutable_executor()->CopyFrom(executorInfo);
1408  operation.mutable_launch_group()->mutable_task_group()->CopyFrom(taskGroup);
1409  return operation;
1410 }
1411 
1412 
1413 template <
1414  typename TResource,
1415  typename TTargetType,
1416  typename TOperationID,
1417  typename TOffer>
1419  const TResource& source,
1420  const TTargetType& targetType,
1421  const Option<std::string>& targetProfile = None(),
1422  const Option<TOperationID>& operationId = None())
1423 {
1424  typename TOffer::Operation operation;
1425  operation.set_type(TOffer::Operation::CREATE_DISK);
1426  operation.mutable_create_disk()->mutable_source()->CopyFrom(source);
1427  operation.mutable_create_disk()->set_target_type(targetType);
1428 
1429  if (targetProfile.isSome()) {
1430  operation.mutable_create_disk()->set_target_profile(targetProfile.get());
1431  }
1432 
1433  if (operationId.isSome()) {
1434  operation.mutable_id()->CopyFrom(operationId.get());
1435  }
1436 
1437  return operation;
1438 }
1439 
1440 
1441 template <typename TResource, typename TOffer>
1442 inline typename TOffer::Operation DESTROY_DISK(const TResource& source)
1443 {
1444  typename TOffer::Operation operation;
1445  operation.set_type(TOffer::Operation::DESTROY_DISK);
1446  operation.mutable_destroy_disk()->mutable_source()->CopyFrom(source);
1447 
1448  return operation;
1449 }
1450 
1451 
1452 template <typename TParameters, typename TParameter>
1453 inline TParameters parameterize(const ACLs& acls)
1454 {
1455  TParameters parameters;
1456  TParameter* parameter = parameters.add_parameter();
1457  parameter->set_key("acls");
1458  parameter->set_value(std::string(jsonify(JSON::Protobuf(acls))));
1459 
1460  return parameters;
1461 }
1462 } // namespace common {
1463 
1464 
1465 // TODO(jmlvanre): Remove `inline` once we have adjusted all tests to
1466 // distinguish between `internal` and `v1`.
1467 inline namespace internal {
1468 template <typename... Args>
1469 inline ExecutorInfo createExecutorInfo(Args&&... args)
1470 {
1472  ExecutorInfo,
1473  ExecutorID,
1474  Resources,
1475  CommandInfo,
1476  FrameworkID>(std::forward<Args>(args)...);
1477 }
1478 
1479 
1480 // We specify the argument to allow brace initialized construction.
1481 inline CommandInfo createCommandInfo(
1482  const Option<std::string>& value = None(),
1483  const std::vector<std::string>& arguments = {})
1484 {
1485  return common::createCommandInfo<CommandInfo>(value, arguments);
1486 }
1487 
1488 
1489 // Almost a direct snippet of code at the bottom of `Slave::launchExecutor`.
1490 inline mesos::slave::ContainerConfig createContainerConfig(
1491  const Option<TaskInfo>& taskInfo,
1492  const ExecutorInfo& executorInfo,
1493  const std::string& sandboxDirectory,
1494  const Option<std::string>& user = None())
1495 {
1496  mesos::slave::ContainerConfig containerConfig;
1497  containerConfig.mutable_executor_info()->CopyFrom(executorInfo);
1498  containerConfig.mutable_command_info()->CopyFrom(executorInfo.command());
1499  containerConfig.mutable_resources()->CopyFrom(executorInfo.resources());
1500  containerConfig.set_directory(sandboxDirectory);
1501 
1502  if (user.isSome()) {
1503  containerConfig.set_user(user.get());
1504  }
1505 
1506  if (taskInfo.isSome()) {
1507  containerConfig.mutable_task_info()->CopyFrom(taskInfo.get());
1508 
1509  if (taskInfo->has_container()) {
1510  containerConfig.mutable_container_info()->CopyFrom(taskInfo->container());
1511  }
1512  } else {
1513  if (executorInfo.has_container()) {
1514  containerConfig.mutable_container_info()
1515  ->CopyFrom(executorInfo.container());
1516  }
1517  }
1518 
1519  return containerConfig;
1520 }
1521 
1522 
1523 // Almost a direct snippet of code in `Slave::Http::_launchNestedContainer`.
1524 inline mesos::slave::ContainerConfig createContainerConfig(
1525  const CommandInfo& commandInfo,
1526  const Option<ContainerInfo>& containerInfo = None(),
1527  const Option<mesos::slave::ContainerClass>& containerClass = None(),
1528  const Option<std::string>& user = None())
1529 {
1530  mesos::slave::ContainerConfig containerConfig;
1531  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1532 
1533  if (user.isSome()) {
1534  containerConfig.set_user(user.get());
1535  }
1536 
1537  if (containerInfo.isSome()) {
1538  containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
1539  }
1540 
1541  if (containerClass.isSome()) {
1542  containerConfig.set_container_class(containerClass.get());
1543  }
1544 
1545  return containerConfig;
1546 }
1547 
1548 
1549 // Helper for creating standalone container configs.
1550 inline mesos::slave::ContainerConfig createContainerConfig(
1551  const CommandInfo& commandInfo,
1552  const std::string& resources,
1553  const std::string& sandboxDirectory,
1554  const Option<ContainerInfo>& containerInfo = None(),
1555  const Option<std::string>& user = None())
1556 {
1557  mesos::slave::ContainerConfig containerConfig;
1558  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1559  containerConfig.mutable_resources()->CopyFrom(
1560  Resources::parse(resources).get());
1561 
1562  containerConfig.set_directory(sandboxDirectory);
1563 
1564  if (user.isSome()) {
1565  containerConfig.set_user(user.get());
1566  }
1567 
1568  if (containerInfo.isSome()) {
1569  containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
1570  }
1571 
1572  return containerConfig;
1573 }
1574 
1575 
1576 template <typename... Args>
1577 inline Image createDockerImage(Args&&... args)
1578 {
1579  return common::createDockerImage<Image>(std::forward<Args>(args)...);
1580 }
1581 
1582 
1583 template <typename... Args>
1584 inline Volume createVolumeSandboxPath(Args&&... args)
1585 {
1586  return common::createVolumeSandboxPath<Volume>(std::forward<Args>(args)...);
1587 }
1588 
1589 
1590 template <typename... Args>
1591 inline Volume createVolumeHostPath(Args&&... args)
1592 {
1593  return common::createVolumeHostPath<Volume, MountPropagation>(
1594  std::forward<Args>(args)...);
1595 }
1596 
1597 
1598 template <typename... Args>
1599 inline Volume createVolumeFromDockerImage(Args&&... args)
1600 {
1601  return common::createVolumeFromDockerImage<Volume, Image>(
1602  std::forward<Args>(args)...);
1603 }
1604 
1605 
1606 template <typename... Args>
1607 inline NetworkInfo createNetworkInfo(Args&&... args)
1608 {
1609  return common::createNetworkInfo<NetworkInfo>(std::forward<Args>(args)...);
1610 }
1611 
1612 
1613 // We specify the argument to allow brace initialized construction.
1614 inline ContainerInfo createContainerInfo(
1615  const Option<std::string>& imageName = None(),
1616  const std::vector<Volume>& volumes = {})
1617 {
1618  return common::createContainerInfo<ContainerInfo, Volume, Image>(
1619  imageName,
1620  volumes);
1621 }
1622 
1623 
1624 template <typename... Args>
1625 inline TaskInfo createTask(Args&&... args)
1626 {
1627  return common::createTask<
1628  TaskInfo,
1629  ExecutorID,
1630  SlaveID,
1631  Resources,
1632  ExecutorInfo,
1633  CommandInfo,
1634  Offer>(std::forward<Args>(args)...);
1635 }
1636 
1637 
1638 // We specify the argument to allow brace initialized construction.
1639 inline TaskGroupInfo createTaskGroupInfo(const std::vector<TaskInfo>& tasks)
1640 {
1641  return common::createTaskGroupInfo<TaskGroupInfo, TaskInfo>(tasks);
1642 }
1643 
1644 
1645 inline Resource::ReservationInfo createStaticReservationInfo(
1646  const std::string& role)
1647 {
1648  return common::createStaticReservationInfo<Resource>(role);
1649 }
1650 
1651 
1652 inline Resource::ReservationInfo createDynamicReservationInfo(
1653  const std::string& role,
1654  const Option<std::string>& principal = None(),
1655  const Option<Labels>& labels = None())
1656 {
1657  return common::createDynamicReservationInfo<Resource, Labels>(
1658  role, principal, labels);
1659 }
1660 
1661 
1662 template <typename... Args>
1663 inline Resource createReservedResource(Args&&... args)
1664 {
1665  return common::createReservedResource<Resource, Resources>(
1666  std::forward<Args>(args)...);
1667 }
1668 
1669 
1670 template <typename... Args>
1671 inline Resource::DiskInfo createDiskInfo(Args&&... args)
1672 {
1673  return common::createDiskInfo<Resource, Volume>(std::forward<Args>(args)...);
1674 }
1675 
1676 
1677 template <typename... Args>
1678 inline Resource::DiskInfo::Source createDiskSourcePath(Args&&... args)
1679 {
1680  return common::createDiskSourcePath<Resource>(std::forward<Args>(args)...);
1681 }
1682 
1683 
1684 template <typename... Args>
1685 inline Resource::DiskInfo::Source createDiskSourceMount(Args&&... args)
1686 {
1687  return common::createDiskSourceMount<Resource>(std::forward<Args>(args)...);
1688 }
1689 
1690 
1691 template <typename... Args>
1692 inline Resource::DiskInfo::Source createDiskSourceBlock(Args&&... args)
1693 {
1694  return common::createDiskSourceBlock<Resource>(std::forward<Args>(args)...);
1695 }
1696 
1697 
1698 template <typename... Args>
1699 inline Resource::DiskInfo::Source createDiskSourceRaw(Args&&... args)
1700 {
1701  return common::createDiskSourceRaw<Resource>(std::forward<Args>(args)...);
1702 }
1703 
1704 
1705 template <typename... Args>
1706 inline Resource createDiskResource(Args&&... args)
1707 {
1708  return common::createDiskResource<Resource, Resources, Volume>(
1709  std::forward<Args>(args)...);
1710 }
1711 
1712 
1713 template <typename... Args>
1714 inline Resource createPersistentVolume(Args&&... args)
1715 {
1716  return common::createPersistentVolume<Resource, Resources, Volume>(
1717  std::forward<Args>(args)...);
1718 }
1719 
1720 
1721 template <typename... Args>
1723 {
1724  return common::createBasicAuthHeaders<Credential>(
1725  std::forward<Args>(args)...);
1726 }
1727 
1728 
1729 template <typename... Args>
1730 inline google::protobuf::RepeatedPtrField<WeightInfo> createWeightInfos(
1731  Args&&... args)
1732 {
1733  return common::createWeightInfos<WeightInfo>(std::forward<Args>(args)...);
1734 }
1735 
1736 
1737 template <typename... Args>
1739 {
1740  return common::convertToHashmap<WeightInfo>(std::forward<Args>(args)...);
1741 }
1742 
1743 
1744 template <typename... Args>
1745 inline DomainInfo createDomainInfo(Args&&... args)
1746 {
1747  return common::createDomainInfo<DomainInfo>(std::forward<Args>(args)...);
1748 }
1749 
1750 
1751 template <typename... Args>
1752 inline Offer::Operation RESERVE(Args&&... args)
1753 {
1754  return common::RESERVE<Resources, OperationID, Offer>(
1755  std::forward<Args>(args)...);
1756 }
1757 
1758 
1759 template <typename... Args>
1760 inline Offer::Operation UNRESERVE(Args&&... args)
1761 {
1762  return common::UNRESERVE<Resources, Offer>(std::forward<Args>(args)...);
1763 }
1764 
1765 
1766 template <typename... Args>
1767 inline Offer::Operation CREATE(Args&&... args)
1768 {
1769  return common::CREATE<Resources, Offer>(std::forward<Args>(args)...);
1770 }
1771 
1772 
1773 template <typename... Args>
1774 inline Offer::Operation DESTROY(Args&&... args)
1775 {
1776  return common::DESTROY<Resources, Offer>(std::forward<Args>(args)...);
1777 }
1778 
1779 
1780 template <typename... Args>
1781 inline Offer::Operation GROW_VOLUME(Args&&... args)
1782 {
1783  return common::GROW_VOLUME<Resource, Offer>(std::forward<Args>(args)...);
1784 }
1785 
1786 
1787 template <typename... Args>
1788 inline Offer::Operation SHRINK_VOLUME(Args&&... args)
1789 {
1790  return common::SHRINK_VOLUME<Resource, Offer>(std::forward<Args>(args)...);
1791 }
1792 
1793 
1794 // We specify the argument to allow brace initialized construction.
1795 inline Offer::Operation LAUNCH(const std::vector<TaskInfo>& tasks)
1796 {
1797  return common::LAUNCH<Offer, TaskInfo>(tasks);
1798 }
1799 
1800 
1801 template <typename... Args>
1802 inline Offer::Operation LAUNCH_GROUP(Args&&... args)
1803 {
1804  return common::LAUNCH_GROUP<ExecutorInfo, TaskGroupInfo, Offer>(
1805  std::forward<Args>(args)...);
1806 }
1807 
1808 
1809 template <typename... Args>
1810 inline Offer::Operation CREATE_DISK(Args&&... args)
1811 {
1812  return common::
1813  CREATE_DISK<Resource, Resource::DiskInfo::Source::Type, OperationID, Offer>(
1814  std::forward<Args>(args)...);
1815 }
1816 
1817 
1818 template <typename... Args>
1819 inline Offer::Operation DESTROY_DISK(Args&&... args)
1820 {
1821  return common::DESTROY_DISK<Resource, Offer>(std::forward<Args>(args)...);
1822 }
1823 
1824 
1825 template <typename... Args>
1826 inline Parameters parameterize(Args&&... args)
1827 {
1828  return common::parameterize<Parameters, Parameter>(
1829  std::forward<Args>(args)...);
1830 }
1831 } // namespace internal {
1832 
1833 
1834 namespace v1 {
1835 template <typename... Args>
1836 inline mesos::v1::ExecutorInfo createExecutorInfo(Args&&... args)
1837 {
1839  mesos::v1::ExecutorInfo,
1840  mesos::v1::ExecutorID,
1842  mesos::v1::CommandInfo,
1843  mesos::v1::FrameworkID>(std::forward<Args>(args)...);
1844 }
1845 
1846 
1847 // We specify the argument to allow brace initialized construction.
1848 inline mesos::v1::CommandInfo createCommandInfo(
1849  const Option<std::string>& value = None(),
1850  const std::vector<std::string>& arguments = {})
1851 {
1852  return common::createCommandInfo<mesos::v1::CommandInfo>(value, arguments);
1853 }
1854 
1855 
1856 template <typename... Args>
1857 inline mesos::v1::Image createDockerImage(Args&&... args)
1858 {
1859  return common::createDockerImage<mesos::v1::Image>(
1860  std::forward<Args>(args)...);
1861 }
1862 
1863 
1864 template <typename... Args>
1865 inline mesos::v1::Volume createVolumeSandboxPath(Args&&... args)
1866 {
1867  return common::createVolumeSandboxPath<mesos::v1::Volume>(
1868  std::forward<Args>(args)...);
1869 }
1870 
1871 
1872 template <typename... Args>
1873 inline mesos::v1::Volume createVolumeHostPath(Args&&... args)
1874 {
1876  mesos::v1::Volume,
1877  mesos::v1::MountPropagation>(std::forward<Args>(args)...);
1878 }
1879 
1880 
1881 template <typename... Args>
1882 inline mesos::v1::Volume createVolumeFromDockerImage(Args&&... args)
1883 {
1885  mesos::v1::Volume, mesos::v1::Image>(std::forward<Args>(args)...);
1886 }
1887 
1888 
1889 template <typename... Args>
1890 inline mesos::v1::NetworkInfo createNetworkInfo(Args&&... args)
1891 {
1892  return common::createNetworkInfo<mesos::v1::NetworkInfo>(
1893  std::forward<Args>(args)...);
1894 }
1895 
1896 
1897 // We specify the argument to allow brace initialized construction.
1898 inline mesos::v1::ContainerInfo createContainerInfo(
1899  const Option<std::string>& imageName = None(),
1900  const std::vector<mesos::v1::Volume>& volumes = {})
1901 {
1903  mesos::v1::ContainerInfo, mesos::v1::Volume, mesos::v1::Image>(
1904  imageName, volumes);
1905 }
1906 
1907 
1908 template <typename... Args>
1909 inline mesos::v1::TaskInfo createTask(Args&&... args)
1910 {
1911  return common::createTask<
1912  mesos::v1::TaskInfo,
1913  mesos::v1::ExecutorID,
1914  mesos::v1::AgentID,
1916  mesos::v1::ExecutorInfo,
1917  mesos::v1::CommandInfo,
1918  mesos::v1::Offer>(std::forward<Args>(args)...);
1919 }
1920 
1921 
1922 // We specify the argument to allow brace initialized construction.
1923 inline mesos::v1::TaskGroupInfo createTaskGroupInfo(
1924  const std::vector<mesos::v1::TaskInfo>& tasks)
1925 {
1927  mesos::v1::TaskGroupInfo,
1928  mesos::v1::TaskInfo>(tasks);
1929 }
1930 
1931 
1932 inline mesos::v1::Resource::ReservationInfo createStaticReservationInfo(
1933  const std::string& role)
1934 {
1935  return common::createStaticReservationInfo<mesos::v1::Resource>(role);
1936 }
1937 
1938 
1939 inline mesos::v1::Resource::ReservationInfo createDynamicReservationInfo(
1940  const std::string& role,
1941  const Option<std::string>& principal = None(),
1942  const Option<mesos::v1::Labels>& labels = None())
1943 {
1945  mesos::v1::Resource, mesos::v1::Labels>(role, principal, labels);
1946 }
1947 
1948 
1949 template <typename... Args>
1950 inline mesos::v1::Resource createReservedResource(Args&&... args)
1951 {
1953  mesos::v1::Resource, mesos::v1::Resources>(std::forward<Args>(args)...);
1954 }
1955 
1956 
1957 template <typename... Args>
1958 inline mesos::v1::Resource::DiskInfo createDiskInfo(Args&&... args)
1959 {
1960  return common::createDiskInfo<mesos::v1::Resource, mesos::v1::Volume>(
1961  std::forward<Args>(args)...);
1962 }
1963 
1964 
1965 template <typename... Args>
1966 inline mesos::v1::Resource::DiskInfo::Source createDiskSourcePath(
1967  Args&&... args)
1968 {
1969  return common::createDiskSourcePath<mesos::v1::Resource>(
1970  std::forward<Args>(args)...);
1971 }
1972 
1973 
1974 template <typename... Args>
1975 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceMount(
1976  Args&&... args)
1977 {
1978  return common::createDiskSourceMount<mesos::v1::Resource>(
1979  std::forward<Args>(args)...);
1980 }
1981 
1982 
1983 template <typename... Args>
1984 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(
1985  Args&&... args)
1986 {
1987  return common::createDiskSourceBlock<mesos::v1::Resource>(
1988  std::forward<Args>(args)...);
1989 }
1990 
1991 
1992 template <typename... Args>
1993 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceRaw(
1994  Args&&... args)
1995 {
1996  return common::createDiskSourceRaw<mesos::v1::Resource>(
1997  std::forward<Args>(args)...);
1998 }
1999 
2000 
2001 template <typename... Args>
2002 inline mesos::v1::Resource createDiskResource(Args&&... args)
2003 {
2005  mesos::v1::Resource,
2007  mesos::v1::Volume>(std::forward<Args>(args)...);
2008 }
2009 
2010 
2011 template <typename... Args>
2012 inline mesos::v1::Resource createPersistentVolume(Args&&... args)
2013 {
2015  mesos::v1::Resource,
2017  mesos::v1::Volume>(std::forward<Args>(args)...);
2018 }
2019 
2020 
2021 template <typename... Args>
2023 {
2024  return common::createBasicAuthHeaders<mesos::v1::Credential>(
2025  std::forward<Args>(args)...);
2026 }
2027 
2028 
2029 template <typename... Args>
2030 inline google::protobuf::RepeatedPtrField<
2031  mesos::v1::WeightInfo> createWeightInfos(Args&&... args)
2032 {
2033  return common::createWeightInfos<mesos::v1::WeightInfo>(
2034  std::forward<Args>(args)...);
2035 }
2036 
2037 
2038 template <typename... Args>
2040 {
2041  return common::convertToHashmap<mesos::v1::WeightInfo>(
2042  std::forward<Args>(args)...);
2043 }
2044 
2045 
2046 template <typename... Args>
2047 inline mesos::v1::Offer::Operation RESERVE(Args&&... args)
2048 {
2049  return common::RESERVE<
2051  mesos::v1::OperationID,
2052  mesos::v1::Offer>(std::forward<Args>(args)...);
2053 }
2054 
2055 
2056 template <typename... Args>
2058 {
2059  return common::UNRESERVE<mesos::v1::Resources, mesos::v1::Offer>(
2060  std::forward<Args>(args)...);
2061 }
2062 
2063 
2064 template <typename... Args>
2065 inline mesos::v1::Offer::Operation CREATE(Args&&... args)
2066 {
2067  return common::CREATE<mesos::v1::Resources, mesos::v1::Offer>(
2068  std::forward<Args>(args)...);
2069 }
2070 
2071 
2072 template <typename... Args>
2073 inline mesos::v1::Offer::Operation DESTROY(Args&&... args)
2074 {
2075  return common::DESTROY<mesos::v1::Resources, mesos::v1::Offer>(
2076  std::forward<Args>(args)...);
2077 }
2078 
2079 
2080 template <typename... Args>
2082 {
2083  return common::GROW_VOLUME<mesos::v1::Resource, mesos::v1::Offer>(
2084  std::forward<Args>(args)...);
2085 }
2086 
2087 
2088 template <typename... Args>
2090 {
2091  return common::SHRINK_VOLUME<mesos::v1::Resource, mesos::v1::Offer>(
2092  std::forward<Args>(args)...);
2093 }
2094 
2095 
2096 // We specify the argument to allow brace initialized construction.
2098  const std::vector<mesos::v1::TaskInfo>& tasks)
2099 {
2100  return common::LAUNCH<mesos::v1::Offer, mesos::v1::TaskInfo>(tasks);
2101 }
2102 
2103 
2104 template <typename... Args>
2106 {
2107  return common::LAUNCH_GROUP<
2108  mesos::v1::ExecutorInfo,
2109  mesos::v1::TaskGroupInfo,
2110  mesos::v1::Offer>(std::forward<Args>(args)...);
2111 }
2112 
2113 
2114 template <typename... Args>
2116 {
2117  return common::CREATE_DISK<
2118  mesos::v1::Resource,
2120  mesos::v1::OperationID,
2121  mesos::v1::Offer>(std::forward<Args>(args)...);
2122 }
2123 
2124 
2125 template <typename... Args>
2127 {
2128  return common::DESTROY_DISK<mesos::v1::Resource, mesos::v1::Offer>(
2129  std::forward<Args>(args)...);
2130 }
2131 
2132 
2133 template <typename... Args>
2134 inline mesos::v1::Parameters parameterize(Args&&... args)
2135 {
2136  return common::parameterize<mesos::v1::Parameters, mesos::v1::Parameter>(
2137  std::forward<Args>(args)...);
2138 }
2139 
2140 
2142  const mesos::v1::FrameworkID& frameworkId,
2143  const mesos::v1::Offer& offer,
2144  const std::vector<mesos::v1::Offer::Operation>& operations,
2146 {
2148  call.set_type(mesos::v1::scheduler::Call::ACCEPT);
2149  call.mutable_framework_id()->CopyFrom(frameworkId);
2150 
2151  mesos::v1::scheduler::Call::Accept* accept = call.mutable_accept();
2152  accept->add_offer_ids()->CopyFrom(offer.id());
2153 
2154  foreach (const mesos::v1::Offer::Operation& operation, operations) {
2155  accept->add_operations()->CopyFrom(operation);
2156  }
2157 
2158  if (filters.isSome()) {
2159  accept->mutable_filters()->CopyFrom(filters.get());
2160  }
2161 
2162  return call;
2163 }
2164 
2165 
2167  const mesos::v1::FrameworkID& frameworkId,
2168  const mesos::v1::AgentID& agentId,
2169  const mesos::v1::scheduler::Event::Update& update)
2170 {
2172  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE);
2173  call.mutable_framework_id()->CopyFrom(frameworkId);
2174 
2175  mesos::v1::scheduler::Call::Acknowledge* acknowledge =
2176  call.mutable_acknowledge();
2177 
2178  acknowledge->mutable_task_id()->CopyFrom(
2179  update.status().task_id());
2180 
2181  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2182  acknowledge->set_uuid(update.status().uuid());
2183 
2184  return call;
2185 }
2186 
2187 
2189  const mesos::v1::FrameworkID& frameworkId,
2190  const mesos::v1::AgentID& agentId,
2191  const mesos::v1::ResourceProviderID& resourceProviderId,
2192  const mesos::v1::scheduler::Event::UpdateOperationStatus& update)
2193 {
2195  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE_OPERATION_STATUS);
2196  call.mutable_framework_id()->CopyFrom(frameworkId);
2197 
2198  mesos::v1::scheduler::Call::AcknowledgeOperationStatus* acknowledge =
2199  call.mutable_acknowledge_operation_status();
2200 
2201  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2202  acknowledge->mutable_resource_provider_id()->CopyFrom(resourceProviderId);
2203  acknowledge->set_uuid(update.status().uuid().value());
2204  acknowledge->mutable_operation_id()->CopyFrom(update.status().operation_id());
2205 
2206  return call;
2207 }
2208 
2209 
2211  const mesos::v1::FrameworkID& frameworkId,
2212  const mesos::v1::TaskID& taskId,
2213  const Option<mesos::v1::AgentID>& agentId = None(),
2214  const Option<mesos::v1::KillPolicy>& killPolicy = None())
2215 {
2217  call.set_type(mesos::v1::scheduler::Call::KILL);
2218  call.mutable_framework_id()->CopyFrom(frameworkId);
2219 
2220  mesos::v1::scheduler::Call::Kill* kill = call.mutable_kill();
2221  kill->mutable_task_id()->CopyFrom(taskId);
2222 
2223  if (agentId.isSome()) {
2224  kill->mutable_agent_id()->CopyFrom(agentId.get());
2225  }
2226 
2227  if (killPolicy.isSome()) {
2228  kill->mutable_kill_policy()->CopyFrom(killPolicy.get());
2229  }
2230 
2231  return call;
2232 }
2233 
2234 
2236  const mesos::v1::FrameworkID& frameworkId,
2237  const std::vector<
2239  operations = {})
2240 {
2242  call.set_type(mesos::v1::scheduler::Call::RECONCILE_OPERATIONS);
2243  call.mutable_framework_id()->CopyFrom(frameworkId);
2244 
2245  mesos::v1::scheduler::Call::ReconcileOperations* reconcile =
2246  call.mutable_reconcile_operations();
2247 
2248  foreach (
2250  operation,
2251  operations) {
2252  reconcile->add_operations()->CopyFrom(operation);
2253  }
2254 
2255  return call;
2256 }
2257 
2258 
2260  const mesos::v1::FrameworkInfo& frameworkInfo,
2261  const Option<mesos::v1::FrameworkID>& frameworkId = None())
2262 {
2264  call.set_type(mesos::v1::scheduler::Call::SUBSCRIBE);
2265 
2266  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2267 
2268  if (frameworkId.isSome()) {
2269  call.mutable_framework_id()->CopyFrom(frameworkId.get());
2270  }
2271 
2272  return call;
2273 }
2274 
2275 } // namespace v1 {
2276 
2277 
2278 inline mesos::Environment createEnvironment(
2280 {
2281  mesos::Environment environment;
2282  foreachpair (const std::string& key, const std::string& value, map) {
2283  mesos::Environment::Variable* variable = environment.add_variables();
2284  variable->set_name(key);
2285  variable->set_value(value);
2286  }
2287  return environment;
2288 }
2289 
2290 
2291 // Macros to get/create (default) ExecutorInfos and FrameworkInfos.
2292 #define DEFAULT_EXECUTOR_INFO createExecutorInfo("default", "exit 1")
2293 
2294 
2295 #define DEFAULT_CREDENTIAL DefaultCredential::create()
2296 #define DEFAULT_CREDENTIAL_2 DefaultCredential2::create()
2297 
2298 
2299 #define DEFAULT_FRAMEWORK_INFO DefaultFrameworkInfo::create()
2300 
2301 
2302 #define DEFAULT_EXECUTOR_ID DEFAULT_EXECUTOR_INFO.executor_id()
2303 
2304 
2305 // Definition of a mock Scheduler to be used in tests with gmock.
2306 class MockScheduler : public Scheduler
2307 {
2308 public:
2309  MockScheduler();
2310  ~MockScheduler() override;
2311 
2312  MOCK_METHOD3(registered, void(SchedulerDriver*,
2313  const FrameworkID&,
2314  const MasterInfo&));
2315  MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
2316  MOCK_METHOD1(disconnected, void(SchedulerDriver*));
2317  MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
2318  const std::vector<Offer>&));
2319  MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
2320  MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
2321  MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
2322  const ExecutorID&,
2323  const SlaveID&,
2324  const std::string&));
2325  MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
2326  MOCK_METHOD4(executorLost, void(SchedulerDriver*,
2327  const ExecutorID&,
2328  const SlaveID&,
2329  int));
2330  MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
2331 };
2332 
2333 // For use with a MockScheduler, for example:
2334 // EXPECT_CALL(sched, resourceOffers(_, _))
2335 // .WillOnce(LaunchTasks(EXECUTOR, TASKS, CPUS, MEM, ROLE));
2336 // Launches up to TASKS no-op tasks, if possible,
2337 // each with CPUS cpus and MEM memory and EXECUTOR executor.
2338 ACTION_P5(LaunchTasks, executor, tasks, cpus, mem, role)
2339 {
2340  SchedulerDriver* driver = arg0;
2341  std::vector<Offer> offers = arg1;
2342  int numTasks = tasks;
2343 
2344  int launched = 0;
2345  for (size_t i = 0; i < offers.size(); i++) {
2346  const Offer& offer = offers[i];
2347 
2348  Resources taskResources = Resources::parse(
2349  "cpus:" + stringify(cpus) + ";mem:" + stringify(mem)).get();
2350 
2351  if (offer.resources_size() > 0 &&
2352  offer.resources(0).has_allocation_info()) {
2353  taskResources.allocate(role);
2354  }
2355 
2356  int nextTaskId = 0;
2357  std::vector<TaskInfo> tasks;
2358  Resources remaining = offer.resources();
2359 
2360  while (remaining.toUnreserved().contains(taskResources) &&
2361  launched < numTasks) {
2362  TaskInfo task;
2363  task.set_name("TestTask");
2364  task.mutable_task_id()->set_value(stringify(nextTaskId++));
2365  task.mutable_slave_id()->MergeFrom(offer.slave_id());
2366  task.mutable_executor()->MergeFrom(executor);
2367 
2368  Option<Resources> resources = remaining.find(
2369  role == std::string("*")
2370  ? taskResources
2371  : taskResources.pushReservation(createStaticReservationInfo(role)));
2372 
2373  CHECK_SOME(resources);
2374 
2375  task.mutable_resources()->MergeFrom(resources.get());
2376  remaining -= resources.get();
2377 
2378  tasks.push_back(task);
2379  launched++;
2380  }
2381 
2382  driver->launchTasks(offer.id(), tasks);
2383  }
2384 }
2385 
2386 
2387 // Like LaunchTasks, but decline the entire offer and
2388 // don't launch any tasks.
2389 ACTION(DeclineOffers)
2390 {
2391  SchedulerDriver* driver = arg0;
2392  std::vector<Offer> offers = arg1;
2393 
2394  for (size_t i = 0; i < offers.size(); i++) {
2395  driver->declineOffer(offers[i].id());
2396  }
2397 }
2398 
2399 
2400 // Like DeclineOffers, but takes a custom filters object.
2401 ACTION_P(DeclineOffers, filters)
2402 {
2403  SchedulerDriver* driver = arg0;
2404  std::vector<Offer> offers = arg1;
2405 
2406  for (size_t i = 0; i < offers.size(); i++) {
2407  driver->declineOffer(offers[i].id(), filters);
2408  }
2409 }
2410 
2411 
2412 // For use with a MockScheduler, for example:
2413 // process::Queue<Offer> offers;
2414 // EXPECT_CALL(sched, resourceOffers(_, _))
2415 // .WillRepeatedly(EnqueueOffers(&offers));
2416 // Enqueues all received offers into the provided queue.
2417 ACTION_P(EnqueueOffers, queue)
2418 {
2419  std::vector<Offer> offers = arg1;
2420  foreach (const Offer& offer, offers) {
2421  queue->put(offer);
2422  }
2423 }
2424 
2425 
2426 // Definition of a mock Executor to be used in tests with gmock.
2427 class MockExecutor : public Executor
2428 {
2429 public:
2430  MockExecutor(const ExecutorID& _id);
2431  ~MockExecutor() override;
2432 
2433  MOCK_METHOD4(registered, void(ExecutorDriver*,
2434  const ExecutorInfo&,
2435  const FrameworkInfo&,
2436  const SlaveInfo&));
2437  MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
2438  MOCK_METHOD1(disconnected, void(ExecutorDriver*));
2439  MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
2440  MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
2441  MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
2442  MOCK_METHOD1(shutdown, void(ExecutorDriver*));
2443  MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
2444 
2445  const ExecutorID id;
2446 };
2447 
2448 
2450 {
2451 public:
2453  Scheduler* scheduler,
2456  scheduler,
2458  "",
2459  true,
2461  {
2462  // No-op destructor as _detector lives on the stack.
2463  detector =
2464  std::shared_ptr<mesos::master::detector::MasterDetector>(
2465  _detector, [](mesos::master::detector::MasterDetector*) {});
2466  }
2467 
2469  Scheduler* scheduler,
2471  const FrameworkInfo& framework,
2472  bool implicitAcknowledgements = true)
2474  scheduler,
2475  framework,
2476  "",
2477  implicitAcknowledgements,
2479  {
2480  // No-op destructor as _detector lives on the stack.
2481  detector =
2482  std::shared_ptr<mesos::master::detector::MasterDetector>(
2483  _detector, [](mesos::master::detector::MasterDetector*) {});
2484  }
2485 
2487  Scheduler* scheduler,
2489  const FrameworkInfo& framework,
2490  bool implicitAcknowledgements,
2491  const Credential& credential)
2493  scheduler,
2494  framework,
2495  "",
2496  implicitAcknowledgements,
2497  credential)
2498  {
2499  // No-op destructor as _detector lives on the stack.
2500  detector =
2501  std::shared_ptr<mesos::master::detector::MasterDetector>(
2502  _detector, [](mesos::master::detector::MasterDetector*) {});
2503  }
2504 };
2505 
2506 
2507 namespace scheduler {
2508 
2509 // A generic mock HTTP scheduler to be used in tests with gmock.
2510 template <typename Mesos, typename Event>
2512 {
2513 public:
2514  MOCK_METHOD1_T(connected, void(Mesos*));
2515  MOCK_METHOD1_T(disconnected, void(Mesos*));
2516  MOCK_METHOD1_T(heartbeat, void(Mesos*));
2517  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
2518  MOCK_METHOD2_T(offers, void(Mesos*, const typename Event::Offers&));
2519  MOCK_METHOD2_T(
2520  inverseOffers,
2521  void(Mesos*, const typename Event::InverseOffers&));
2522  MOCK_METHOD2_T(rescind, void(Mesos*, const typename Event::Rescind&));
2523  MOCK_METHOD2_T(
2524  rescindInverseOffers,
2525  void(Mesos*, const typename Event::RescindInverseOffer&));
2526  MOCK_METHOD2_T(update, void(Mesos*, const typename Event::Update&));
2527  MOCK_METHOD2_T(
2528  updateOperationStatus,
2529  void(Mesos*, const typename Event::UpdateOperationStatus&));
2530  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
2531  MOCK_METHOD2_T(failure, void(Mesos*, const typename Event::Failure&));
2532  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
2533 
2534  void events(Mesos* mesos, std::queue<Event> events)
2535  {
2536  while (!events.empty()) {
2537  Event event = std::move(events.front());
2538  events.pop();
2539 
2540  switch (event.type()) {
2541  case Event::SUBSCRIBED:
2542  subscribed(mesos, event.subscribed());
2543  break;
2544  case Event::OFFERS:
2545  offers(mesos, event.offers());
2546  break;
2547  case Event::INVERSE_OFFERS:
2548  inverseOffers(mesos, event.inverse_offers());
2549  break;
2550  case Event::RESCIND:
2551  rescind(mesos, event.rescind());
2552  break;
2553  case Event::RESCIND_INVERSE_OFFER:
2554  rescindInverseOffers(mesos, event.rescind_inverse_offer());
2555  break;
2556  case Event::UPDATE:
2557  update(mesos, event.update());
2558  break;
2559  case Event::UPDATE_OPERATION_STATUS:
2560  updateOperationStatus(mesos, event.update_operation_status());
2561  break;
2562  case Event::MESSAGE:
2563  message(mesos, event.message());
2564  break;
2565  case Event::FAILURE:
2566  failure(mesos, event.failure());
2567  break;
2568  case Event::ERROR:
2569  error(mesos, event.error());
2570  break;
2571  case Event::HEARTBEAT:
2572  heartbeat(mesos);
2573  break;
2574  case Event::UNKNOWN:
2575  LOG(FATAL) << "Received unexpected UNKNOWN event";
2576  break;
2577  }
2578  }
2579  }
2580 };
2581 
2582 
2583 // A generic testing interface for the scheduler library that can be used to
2584 // test the library across various versions.
2585 template <typename Mesos, typename Event>
2586 class TestMesos : public Mesos
2587 {
2588 public:
2590  const std::string& master,
2591  ContentType contentType,
2592  const std::shared_ptr<MockHTTPScheduler<Mesos, Event>>& scheduler,
2593  const Option<std::shared_ptr<mesos::master::detector::MasterDetector>>&
2594  detector = None())
2595  : Mesos(
2596  master,
2597  contentType,
2598  lambda::bind(&MockHTTPScheduler<Mesos, Event>::connected,
2599  scheduler,
2600  this),
2601  lambda::bind(&MockHTTPScheduler<Mesos, Event>::disconnected,
2602  scheduler,
2603  this),
2604  lambda::bind(&MockHTTPScheduler<Mesos, Event>::events,
2605  scheduler,
2606  this,
2607  lambda::_1),
2608  v1::DEFAULT_CREDENTIAL,
2609  detector) {}
2610 
2611  ~TestMesos() override
2612  {
2613  // Since the destructor for `TestMesos` is invoked first, the library can
2614  // make more callbacks to the `scheduler` object before the `Mesos` (base
2615  // class) destructor is invoked. To prevent this, we invoke `stop()` here
2616  // to explicitly stop the library.
2617  this->stop();
2618 
2619  bool paused = process::Clock::paused();
2620 
2621  // Need to settle the Clock to ensure that all the pending async callbacks
2622  // with references to `this` and `scheduler` queued on libprocess are
2623  // executed before the object is destructed.
2626 
2627  // Return the Clock to its original state.
2628  if (!paused) {
2630  }
2631  }
2632 };
2633 
2634 } // namespace scheduler {
2635 
2636 
2637 namespace v1 {
2638 namespace scheduler {
2639 
2645 
2646 
2650 
2651 
2652 // This matcher is used to match an offer event that contains a vector of offers
2653 // having any resource that passes the filter.
2654 MATCHER_P(OffersHaveAnyResource, filter, "")
2655 {
2656  foreach (const Offer& offer, arg.offers()) {
2657  foreach (const Resource& resource, offer.resources()) {
2658  if (filter(resource)) {
2659  return true;
2660  }
2661  }
2662  }
2663 
2664  return false;
2665 }
2666 
2667 
2668 // Like LaunchTasks, but decline the entire offer and don't launch any tasks.
2669 ACTION(DeclineOffers)
2670 {
2671  Call call;
2672  call.set_type(Call::DECLINE);
2673 
2674  Call::Decline* decline = call.mutable_decline();
2675 
2676  foreach (const Offer& offer, arg1.offers()) {
2677  decline->add_offer_ids()->CopyFrom(offer.id());
2678 
2679  if (!call.has_framework_id()) {
2680  call.mutable_framework_id()->CopyFrom(offer.framework_id());
2681  }
2682  }
2683 
2684  arg0->send(call);
2685 }
2686 
2687 
2688 ACTION_P(SendSubscribe, frameworkInfo)
2689 {
2690  Call call;
2691  call.set_type(Call::SUBSCRIBE);
2692  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2693 
2694  arg0->send(call);
2695 }
2696 
2697 
2698 ACTION_P2(SendSubscribe, frameworkInfo, frameworkId)
2699 {
2700  Call call;
2701  call.set_type(Call::SUBSCRIBE);
2702  call.mutable_framework_id()->CopyFrom(frameworkId);
2703  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2704  call.mutable_subscribe()->mutable_framework_info()->mutable_id()->CopyFrom(
2705  frameworkId);
2706 
2707  arg0->send(call);
2708 }
2709 
2710 
2711 ACTION_P2(SendAcknowledge, frameworkId, agentId)
2712 {
2713  Call call;
2714  call.set_type(Call::ACKNOWLEDGE);
2715  call.mutable_framework_id()->CopyFrom(frameworkId);
2716 
2717  Call::Acknowledge* acknowledge = call.mutable_acknowledge();
2718  acknowledge->mutable_task_id()->CopyFrom(arg1.status().task_id());
2719  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2720  acknowledge->set_uuid(arg1.status().uuid());
2721 
2722  arg0->send(call);
2723 }
2724 
2725 
2727  SendAcknowledgeOperationStatus, frameworkId, agentId, resourceProviderId)
2728 {
2729  Call call;
2730  call.set_type(Call::ACKNOWLEDGE_OPERATION_STATUS);
2731  call.mutable_framework_id()->CopyFrom(frameworkId);
2732 
2733  Call::AcknowledgeOperationStatus* acknowledge =
2734  call.mutable_acknowledge_operation_status();
2735 
2736  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2737  acknowledge->mutable_resource_provider_id()->CopyFrom(resourceProviderId);
2738  acknowledge->set_uuid(arg1.status().uuid().value());
2739  acknowledge->mutable_operation_id()->CopyFrom(arg1.status().operation_id());
2740 
2741  arg0->send(call);
2742 }
2743 
2744 } // namespace scheduler {
2745 
2749 
2750 } // namespace v1 {
2751 
2752 
2753 namespace executor {
2754 
2755 // A generic mock HTTP executor to be used in tests with gmock.
2756 template <typename Mesos, typename Event>
2758 {
2759 public:
2760  MOCK_METHOD1_T(connected, void(Mesos*));
2761  MOCK_METHOD1_T(disconnected, void(Mesos*));
2762  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
2763  MOCK_METHOD2_T(launch, void(Mesos*, const typename Event::Launch&));
2764  MOCK_METHOD2_T(launchGroup, void(Mesos*, const typename Event::LaunchGroup&));
2765  MOCK_METHOD2_T(kill, void(Mesos*, const typename Event::Kill&));
2766  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
2767  MOCK_METHOD1_T(shutdown, void(Mesos*));
2768  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
2769  MOCK_METHOD2_T(acknowledged,
2770  void(Mesos*, const typename Event::Acknowledged&));
2771 
2772  void events(Mesos* mesos, std::queue<Event> events)
2773  {
2774  while (!events.empty()) {
2775  Event event = std::move(events.front());
2776  events.pop();
2777 
2778  switch (event.type()) {
2779  case Event::SUBSCRIBED:
2780  subscribed(mesos, event.subscribed());
2781  break;
2782  case Event::LAUNCH:
2783  launch(mesos, event.launch());
2784  break;
2785  case Event::LAUNCH_GROUP:
2786  launchGroup(mesos, event.launch_group());
2787  break;
2788  case Event::KILL:
2789  kill(mesos, event.kill());
2790  break;
2791  case Event::ACKNOWLEDGED:
2792  acknowledged(mesos, event.acknowledged());
2793  break;
2794  case Event::MESSAGE:
2795  message(mesos, event.message());
2796  break;
2797  case Event::SHUTDOWN:
2798  shutdown(mesos);
2799  break;
2800  case Event::ERROR:
2801  error(mesos, event.error());
2802  break;
2803  case Event::UNKNOWN:
2804  LOG(FATAL) << "Received unexpected UNKNOWN event";
2805  break;
2806  }
2807  }
2808  }
2809 };
2810 
2811 
2812 // A generic testing interface for the executor library that can be used to
2813 // test the library across various versions.
2814 template <typename Mesos, typename Event>
2815 class TestMesos : public Mesos
2816 {
2817 public:
2819  ContentType contentType,
2820  const std::shared_ptr<MockHTTPExecutor<Mesos, Event>>& executor,
2821  const std::map<std::string, std::string>& environment)
2822  : Mesos(
2823  contentType,
2824  lambda::bind(&MockHTTPExecutor<Mesos, Event>::connected,
2825  executor,
2826  this),
2827  lambda::bind(&MockHTTPExecutor<Mesos, Event>::disconnected,
2828  executor,
2829  this),
2830  lambda::bind(&MockHTTPExecutor<Mesos, Event>::events,
2831  executor,
2832  this,
2833  lambda::_1),
2834  environment) {}
2835 };
2836 
2837 } // namespace executor {
2838 
2839 
2840 namespace v1 {
2841 namespace executor {
2842 
2843 // Alias existing `mesos::v1::executor` classes so that we can easily
2844 // write `v1::executor::` in tests.
2848 
2849 
2853 
2854 
2855 // TODO(anand): Move these actions to the `v1::executor` namespace.
2856 ACTION_P2(SendSubscribe, frameworkId, executorId)
2857 {
2859  call.mutable_framework_id()->CopyFrom(frameworkId);
2860  call.mutable_executor_id()->CopyFrom(executorId);
2861 
2862  call.set_type(mesos::v1::executor::Call::SUBSCRIBE);
2863 
2864  call.mutable_subscribe();
2865 
2866  arg0->send(call);
2867 }
2868 
2869 
2870 ACTION_P3(SendUpdateFromTask, frameworkId, executorId, state)
2871 {
2872  mesos::v1::TaskStatus status;
2873  status.mutable_task_id()->CopyFrom(arg1.task().task_id());
2874  status.mutable_executor_id()->CopyFrom(executorId);
2875  status.set_state(state);
2876  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
2877  status.set_uuid(id::UUID::random().toBytes());
2878 
2880  call.mutable_framework_id()->CopyFrom(frameworkId);
2881  call.mutable_executor_id()->CopyFrom(executorId);
2882 
2883  call.set_type(mesos::v1::executor::Call::UPDATE);
2884 
2885  call.mutable_update()->mutable_status()->CopyFrom(status);
2886 
2887  arg0->send(call);
2888 }
2889 
2890 
2891 ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
2892 {
2893  mesos::v1::TaskStatus status;
2894  status.mutable_task_id()->CopyFrom(arg1.task_id());
2895  status.mutable_executor_id()->CopyFrom(executorId);
2896  status.set_state(state);
2897  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
2898  status.set_uuid(id::UUID::random().toBytes());
2899 
2901  call.mutable_framework_id()->CopyFrom(frameworkId);
2902  call.mutable_executor_id()->CopyFrom(executorId);
2903 
2904  call.set_type(mesos::v1::executor::Call::UPDATE);
2905 
2906  call.mutable_update()->mutable_status()->CopyFrom(status);
2907 
2908  arg0->send(call);
2909 }
2910 
2911 } // namespace executor {
2912 
2916 
2917 } // namespace v1 {
2918 
2919 
2920 namespace resource_provider {
2921 
2922 template <
2923  typename Event,
2924  typename Call,
2925  typename Driver,
2926  typename ResourceProviderInfo,
2927  typename Resource,
2928  typename Resources,
2929  typename ResourceProviderID,
2930  typename OperationState,
2931  typename Operation,
2932  typename Source>
2934 {
2936  Event,
2937  Call,
2938  Driver,
2939  ResourceProviderInfo,
2940  Resource,
2941  Resources,
2942  ResourceProviderID,
2943  OperationState,
2944  Operation,
2945  Source>;
2946 
2947 public:
2949  const ResourceProviderInfo& _info,
2950  const Option<Resources>& _resources = None())
2951  : info(_info),
2952  resources(_resources)
2953  {
2954  ON_CALL(*this, connected())
2955  .WillByDefault(Invoke(this, &MockResourceProviderT::connectedDefault));
2956  EXPECT_CALL(*this, connected()).WillRepeatedly(DoDefault());
2957 
2958  ON_CALL(*this, subscribed(_))
2959  .WillByDefault(Invoke(this, &MockResourceProviderT::subscribedDefault));
2960  EXPECT_CALL(*this, subscribed(_)).WillRepeatedly(DoDefault());
2961 
2962  ON_CALL(*this, applyOperation(_))
2963  .WillByDefault(Invoke(this, &MockResourceProviderT::operationDefault));
2964  EXPECT_CALL(*this, applyOperation(_)).WillRepeatedly(DoDefault());
2965 
2966  ON_CALL(*this, publishResources(_))
2967  .WillByDefault(Invoke(this, &MockResourceProviderT::publishDefault));
2968  EXPECT_CALL(*this, publishResources(_)).WillRepeatedly(DoDefault());
2969 
2970  ON_CALL(*this, teardown())
2971  .WillByDefault(Invoke(this, &MockResourceProviderT::teardownDefault));
2972  EXPECT_CALL(*this, teardown()).WillRepeatedly(DoDefault());
2973  }
2974 
2975  MOCK_METHOD0_T(connected, void());
2976  MOCK_METHOD0_T(disconnected, void());
2977  MOCK_METHOD1_T(subscribed, void(const typename Event::Subscribed&));
2978  MOCK_METHOD1_T(applyOperation, void(const typename Event::ApplyOperation&));
2979  MOCK_METHOD1_T(
2980  publishResources,
2981  void(const typename Event::PublishResources&));
2982  MOCK_METHOD1_T(
2983  acknowledgeOperationStatus,
2984  void(const typename Event::AcknowledgeOperationStatus&));
2985  MOCK_METHOD1_T(
2986  reconcileOperations,
2987  void(const typename Event::ReconcileOperations&));
2988  MOCK_METHOD0_T(teardown, void());
2989 
2990  void events(std::queue<Event> events)
2991  {
2992  while (!events.empty()) {
2993  Event event = events.front();
2994  events.pop();
2995 
2996  switch (event.type()) {
2997  case Event::SUBSCRIBED:
2998  subscribed(event.subscribed());
2999  break;
3000  case Event::APPLY_OPERATION:
3001  applyOperation(event.apply_operation());
3002  break;
3003  case Event::PUBLISH_RESOURCES:
3004  publishResources(event.publish_resources());
3005  break;
3006  case Event::ACKNOWLEDGE_OPERATION_STATUS:
3007  acknowledgeOperationStatus(event.acknowledge_operation_status());
3008  break;
3009  case Event::RECONCILE_OPERATIONS:
3010  reconcileOperations(event.reconcile_operations());
3011  break;
3012  case Event::TEARDOWN:
3013  teardown();
3014  break;
3015  case Event::UNKNOWN:
3016  LOG(FATAL) << "Received unexpected UNKNOWN event";
3017  break;
3018  }
3019  }
3020  }
3021 
3022  process::Future<Nothing> send(const Call& call)
3023  {
3024  return driver->send(call);
3025  }
3026 
3027  void start(
3029  ContentType contentType)
3030  {
3031  Option<std::string> token;
3032 
3033 #ifdef USE_SSL_SOCKET
3035  DEFAULT_JWT_SECRET_KEY);
3036 
3037  // For resource provider authentication the chosen claims don't matter,
3038  // only the signature has to be valid.
3039  // TODO(nfnt): Revisit this once there's authorization of resource provider
3040  // API calls.
3042  claims["foo"] = "bar";
3043 
3044  process::http::authentication::Principal principal(None(), claims);
3045 
3046  process::Future<Secret> secret = secretGenerator.generate(principal);
3047 
3048  AWAIT_READY(secret);
3049 
3050  token = secret->value().data();
3051 #endif // USE_SSL_SOCKET
3052 
3053  driver.reset(new Driver(
3054  std::move(detector),
3055  contentType,
3056  lambda::bind(&MockResourceProviderT::connected, this),
3057  lambda::bind(&MockResourceProviderT::disconnected, this),
3058  lambda::bind(&MockResourceProviderT::events, this, lambda::_1),
3059  token));
3060 
3061  driver->start();
3062  }
3063 
3065  {
3066  Call call;
3067  call.set_type(Call::SUBSCRIBE);
3068  call.mutable_subscribe()->mutable_resource_provider_info()->CopyFrom(info);
3069 
3070  driver->send(call);
3071  }
3072 
3073  void subscribedDefault(const typename Event::Subscribed& subscribed)
3074  {
3075  info.mutable_id()->CopyFrom(subscribed.provider_id());
3076 
3077  if (resources.isSome()) {
3078  Resources injected;
3079 
3080  foreach (Resource resource, resources.get()) {
3081  resource.mutable_provider_id()->CopyFrom(info.id());
3082  injected += resource;
3083  }
3084 
3085  Call call;
3086  call.set_type(Call::UPDATE_STATE);
3087  call.mutable_resource_provider_id()->CopyFrom(info.id());
3088 
3089  typename Call::UpdateState* update = call.mutable_update_state();
3090  update->mutable_resources()->CopyFrom(injected);
3091  update->mutable_resource_version_uuid()->set_value(
3092  id::UUID::random().toBytes());
3093 
3094  driver->send(call);
3095  }
3096  }
3097 
3098  void operationDefault(const typename Event::ApplyOperation& operation)
3099  {
3100  CHECK(info.has_id());
3101 
3102  Call call;
3103  call.set_type(Call::UPDATE_OPERATION_STATUS);
3104  call.mutable_resource_provider_id()->CopyFrom(info.id());
3105 
3106  typename Call::UpdateOperationStatus* update =
3107  call.mutable_update_operation_status();
3108  update->mutable_framework_id()->CopyFrom(operation.framework_id());
3109  update->mutable_operation_uuid()->CopyFrom(operation.operation_uuid());
3110 
3111  update->mutable_status()->set_state(
3112  OperationState::OPERATION_FINISHED);
3113 
3114  switch (operation.info().type()) {
3115  case Operation::LAUNCH:
3117  break;
3118  case Operation::RESERVE:
3119  break;
3120  case Operation::UNRESERVE:
3121  break;
3122  case Operation::CREATE:
3123  break;
3124  case Operation::DESTROY:
3125  break;
3126  // TODO(zhitao): Implement default operation for `GROW_VOLUME` and
3127  // `SHRINK_VOLUME` on mocked resource provider.
3129  break;
3131  break;
3133  update->mutable_status()->add_converted_resources()->CopyFrom(
3134  operation.info().create_disk().source());
3135  update->mutable_status()
3136  ->mutable_converted_resources(0)
3137  ->mutable_disk()
3138  ->mutable_source()
3139  ->set_type(operation.info().create_disk().target_type());
3140  if (operation.info().create_disk().has_target_profile()) {
3141  update->mutable_status()
3142  ->mutable_converted_resources(0)
3143  ->mutable_disk()
3144  ->mutable_source()
3145  ->set_profile(operation.info().create_disk().target_profile());
3146  }
3147  break;
3149  update->mutable_status()->add_converted_resources()->CopyFrom(
3150  operation.info().destroy_disk().source());
3151  update->mutable_status()
3152  ->mutable_converted_resources(0)
3153  ->mutable_disk()
3154  ->mutable_source()
3155  ->set_type(Source::RAW);
3156  break;
3157  case Operation::UNKNOWN:
3158  break;
3159  }
3160 
3161  if (update->has_status()) {
3162  update->mutable_status()->mutable_resource_provider_id()->CopyFrom(
3163  info.id());
3164 
3165  update->mutable_latest_status()->CopyFrom(update->status());
3166  }
3167 
3168  driver->send(call);
3169  }
3170 
3171  void publishDefault(const typename Event::PublishResources& publish)
3172  {
3173  CHECK(info.has_id());
3174 
3175  Call call;
3176  call.set_type(Call::UPDATE_PUBLISH_RESOURCES_STATUS);
3177  call.mutable_resource_provider_id()->CopyFrom(info.id());
3178 
3179  typename Call::UpdatePublishResourcesStatus* update =
3180  call.mutable_update_publish_resources_status();
3181  update->mutable_uuid()->CopyFrom(publish.uuid());
3182  update->set_status(Call::UpdatePublishResourcesStatus::OK);
3183 
3184  driver->send(call);
3185  }
3186 
3188 
3189  ResourceProviderInfo info;
3190 
3191 private:
3192  Option<Resources> resources;
3193  std::unique_ptr<Driver> driver;
3194 };
3195 
3197  const process::UPID& pid)
3198 {
3199  // Start and register a resource provider.
3200  std::string scheme = "http";
3201 
3202 #ifdef USE_SSL_SOCKET
3204  scheme = "https";
3205  }
3206 #endif
3207 
3208  process::http::URL url(
3209  scheme,
3210  pid.address.ip,
3211  pid.address.port,
3212  pid.id + "/api/v1/resource_provider");
3213 
3215 }
3216 
3217 } // namespace resource_provider {
3218 
3219 
3220 namespace v1 {
3221 namespace resource_provider {
3222 
3223 // Alias existing `mesos::v1::resource_provider` classes so that we can easily
3224 // write `v1::resource_provider::` in tests.
3227 
3228 } // namespace resource_provider {
3229 
3234  mesos::v1::ResourceProviderInfo,
3235  mesos::v1::Resource,
3237  mesos::v1::ResourceProviderID,
3238  mesos::v1::OperationState,
3240  mesos::v1::Resource::DiskInfo::Source>;
3241 
3242 } // namespace v1 {
3243 
3244 
3245 // Definition of a MockAuthorizer that can be used in tests with gmock.
3247 {
3248 public:
3249  MockAuthorizer();
3250  ~MockAuthorizer() override;
3251 
3252  MOCK_METHOD1(
3253  authorized, process::Future<bool>(const authorization::Request& request));
3254 
3255  MOCK_METHOD2(
3256  getObjectApprover, process::Future<process::Owned<ObjectApprover>>(
3257  const Option<authorization::Subject>& subject,
3258  const authorization::Action& action));
3259 };
3260 
3261 
3262 // Definition of a MockGarbageCollector that can be used in tests with gmock.
3264 {
3265 public:
3266  explicit MockGarbageCollector(const std::string& workDir);
3267  ~MockGarbageCollector() override;
3268 
3269  // The default action is to always return `true`.
3270  MOCK_METHOD1(unschedule, process::Future<bool>(const std::string& path));
3271 };
3272 
3273 
3275 {
3276 public:
3277  MockSecretGenerator() = default;
3278  ~MockSecretGenerator() override = default;
3279 
3280  MOCK_METHOD1(generate, process::Future<Secret>(
3281  const process::http::authentication::Principal& principal));
3282 };
3283 
3284 
3285 ACTION_P(SendStatusUpdateFromTask, state)
3286 {
3287  TaskStatus status;
3288  status.mutable_task_id()->MergeFrom(arg1.task_id());
3289  status.set_state(state);
3290  arg0->sendStatusUpdate(status);
3291 }
3292 
3293 
3294 ACTION_P(SendStatusUpdateFromTaskID, state)
3295 {
3296  TaskStatus status;
3297  status.mutable_task_id()->MergeFrom(arg1);
3298  status.set_state(state);
3299  arg0->sendStatusUpdate(status);
3300 }
3301 
3302 
3303 ACTION_P(SendFrameworkMessage, data)
3304 {
3305  arg0->sendFrameworkMessage(data);
3306 }
3307 
3308 
3309 #define FUTURE_PROTOBUF(message, from, to) \
3310  FutureProtobuf(message, from, to)
3311 
3312 
3313 #define DROP_PROTOBUF(message, from, to) \
3314  FutureProtobuf(message, from, to, true)
3315 
3316 
3317 #define DROP_PROTOBUFS(message, from, to) \
3318  DropProtobufs(message, from, to)
3319 
3320 
3321 #define EXPECT_NO_FUTURE_PROTOBUFS(message, from, to) \
3322  ExpectNoFutureProtobufs(message, from, to)
3323 
3324 
3325 #define FUTURE_HTTP_PROTOBUF(message, path, contentType) \
3326  FutureHttp(message, path, contentType)
3327 
3328 
3329 #define DROP_HTTP_PROTOBUF(message, path, contentType) \
3330  FutureHttp(message, path, contentType, true)
3331 
3332 
3333 #define DROP_HTTP_PROTOBUFS(message, path, contentType) \
3334  DropHttpProtobufs(message, path, contentType)
3335 
3336 
3337 #define EXPECT_NO_FUTURE_HTTP_PROTOBUFS(message, path, contentType) \
3338  ExpectNoFutureHttpProtobufs(message, path, contentType)
3339 
3340 
3341 // These are specialized versions of {FUTURE,DROP}_PROTOBUF that
3342 // capture a scheduler/executor Call protobuf of the given 'type'.
3343 // Note that we name methods as '*ProtobufUnion()' because these could
3344 // be reused for macros that capture any protobufs that are described
3345 // using the standard protocol buffer "union" trick (e.g.,
3346 // FUTURE_EVENT to capture scheduler::Event), see
3347 // https://developers.google.com/protocol-buffers/docs/techniques#union.
3348 
3349 #define FUTURE_CALL(message, unionType, from, to) \
3350  FutureUnionProtobuf(message, unionType, from, to)
3351 
3352 
3353 #define DROP_CALL(message, unionType, from, to) \
3354  FutureUnionProtobuf(message, unionType, from, to, true)
3355 
3356 
3357 #define DROP_CALLS(message, unionType, from, to) \
3358  DropUnionProtobufs(message, unionType, from, to)
3359 
3360 
3361 #define EXPECT_NO_FUTURE_CALLS(message, unionType, from, to) \
3362  ExpectNoFutureUnionProtobufs(message, unionType, from, to)
3363 
3364 
3365 #define FUTURE_CALL_MESSAGE(message, unionType, from, to) \
3366  process::FutureUnionMessage(message, unionType, from, to)
3367 
3368 
3369 #define DROP_CALL_MESSAGE(message, unionType, from, to) \
3370  process::FutureUnionMessage(message, unionType, from, to, true)
3371 
3372 
3373 #define FUTURE_HTTP_CALL(message, unionType, path, contentType) \
3374  FutureUnionHttp(message, unionType, path, contentType)
3375 
3376 
3377 #define DROP_HTTP_CALL(message, unionType, path, contentType) \
3378  FutureUnionHttp(message, unionType, path, contentType, true)
3379 
3380 
3381 #define DROP_HTTP_CALLS(message, unionType, path, contentType) \
3382  DropUnionHttpProtobufs(message, unionType, path, contentType)
3383 
3384 
3385 #define EXPECT_NO_FUTURE_HTTP_CALLS(message, unionType, path, contentType) \
3386  ExpectNoFutureUnionHttpProtobufs(message, unionType, path, contentType)
3387 
3388 
3389 // Forward declaration.
3390 template <typename T>
3391 T _FutureProtobuf(const process::Message& message);
3392 
3393 
3394 template <typename T, typename From, typename To>
3395 process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
3396 {
3397  // Help debugging by adding some "type constraints".
3398  { google::protobuf::Message* m = &t; (void) m; }
3399 
3400  return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
3401  .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
3402 }
3403 
3404 
3405 template <typename Message, typename UnionType, typename From, typename To>
3407  Message message, UnionType unionType, From from, To to, bool drop = false)
3408 {
3409  // Help debugging by adding some "type constraints".
3410  { google::protobuf::Message* m = &message; (void) m; }
3411 
3412  return process::FutureUnionMessage(message, unionType, from, to, drop)
3413  .then(lambda::bind(&_FutureProtobuf<Message>, lambda::_1));
3414 }
3415 
3416 
3417 template <typename Message, typename Path>
3419  Message message,
3420  Path path,
3421  ContentType contentType,
3422  bool drop = false)
3423 {
3424  // Help debugging by adding some "type constraints".
3425  { google::protobuf::Message* m = &message; (void) m; }
3426 
3427  auto deserializer =
3428  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3429 
3430  return process::FutureHttpRequest(message, path, deserializer, drop)
3431  .then([deserializer](const process::http::Request& request) {
3432  return deserializer(request.body).get();
3433  });
3434 }
3435 
3436 
3437 template <typename Message, typename UnionType, typename Path>
3439  Message message,
3440  UnionType unionType,
3441  Path path,
3442  ContentType contentType,
3443  bool drop = false)
3444 {
3445  // Help debugging by adding some "type constraints".
3446  { google::protobuf::Message* m = &message; (void) m; }
3447 
3448  auto deserializer =
3449  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3450 
3452  message, unionType, path, deserializer, drop)
3453  .then([deserializer](const process::http::Request& request) {
3454  return deserializer(request.body).get();
3455  });
3456 }
3457 
3458 
3459 template <typename T>
3461 {
3462  T t;
3463  t.ParseFromString(message.body);
3464  return t;
3465 }
3466 
3467 
3468 template <typename T, typename From, typename To>
3469 void DropProtobufs(T t, From from, To to)
3470 {
3471  // Help debugging by adding some "type constraints".
3472  { google::protobuf::Message* m = &t; (void) m; }
3473 
3474  process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
3475 }
3476 
3477 
3478 template <typename Message, typename UnionType, typename From, typename To>
3479 void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
3480 {
3481  // Help debugging by adding some "type constraints".
3482  { google::protobuf::Message* m = &message; (void) m; }
3483 
3484  process::DropUnionMessages(message, unionType, from, to);
3485 }
3486 
3487 
3488 template <typename Message, typename Path>
3490  Message message,
3491  Path path,
3492  ContentType contentType,
3493  bool drop = false)
3494 {
3495  // Help debugging by adding some "type constraints".
3496  { google::protobuf::Message* m = &message; (void) m; }
3497 
3498  auto deserializer =
3499  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3500 
3501  process::DropHttpRequests(message, path, deserializer);
3502 }
3503 
3504 
3505 template <typename Message, typename UnionType, typename Path>
3507  Message message,
3508  UnionType unionType,
3509  Path path,
3510  ContentType contentType,
3511  bool drop = false)
3512 {
3513  // Help debugging by adding some "type constraints".
3514  { google::protobuf::Message* m = &message; (void) m; }
3515 
3516  auto deserializer =
3517  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3518 
3519  process::DropUnionHttpRequests(message, unionType, path, deserializer);
3520 }
3521 
3522 
3523 template <typename T, typename From, typename To>
3524 void ExpectNoFutureProtobufs(T t, From from, To to)
3525 {
3526  // Help debugging by adding some "type constraints".
3527  { google::protobuf::Message* m = &t; (void) m; }
3528 
3529  process::ExpectNoFutureMessages(testing::Eq(t.GetTypeName()), from, to);
3530 }
3531 
3532 
3533 template <typename Message, typename UnionType, typename From, typename To>
3535  Message message, UnionType unionType, From from, To to)
3536 {
3537  // Help debugging by adding some "type constraints".
3538  { google::protobuf::Message* m = &message; (void) m; }
3539 
3540  process::ExpectNoFutureUnionMessages(message, unionType, from, to);
3541 }
3542 
3543 
3544 template <typename Message, typename Path>
3546  Message message,
3547  Path path,
3548  ContentType contentType,
3549  bool drop = false)
3550 {
3551  // Help debugging by adding some "type constraints".
3552  { google::protobuf::Message* m = &message; (void) m; }
3553 
3554  auto deserializer =
3555  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3556 
3557  process::ExpectNoFutureHttpRequests(message, path, deserializer);
3558 }
3559 
3560 
3561 template <typename Message, typename UnionType, typename Path>
3563  Message message,
3564  UnionType unionType,
3565  Path path,
3566  ContentType contentType,
3567  bool drop = false)
3568 {
3569  // Help debugging by adding some "type constraints".
3570  { google::protobuf::Message* m = &message; (void) m; }
3571 
3572  auto deserializer =
3573  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3574 
3576  message, unionType, path, deserializer);
3577 }
3578 
3579 
3580 // This matcher is used to match a vector of resource offers that
3581 // contains an offer having any resource that passes the filter.
3582 MATCHER_P(OffersHaveAnyResource, filter, "")
3583 {
3584  foreach (const Offer& offer, arg) {
3585  foreach (const Resource& resource, offer.resources()) {
3586  if (filter(resource)) {
3587  return true;
3588  }
3589  }
3590  }
3591 
3592  return false;
3593 }
3594 
3595 
3596 // This matcher is used to match a vector of resource offers that
3597 // contains an offer having the specified resource.
3598 MATCHER_P(OffersHaveResource, resource, "")
3599 {
3600  foreach (const Offer& offer, arg) {
3601  Resources resources = offer.resources();
3602 
3603  // If `resource` is not allocated, we are matching offers against
3604  // resources constructed from scratch, so we strip off allocations.
3605  if (!resource.has_allocation_info()) {
3606  resources.unallocate();
3607  }
3608 
3609  if (resources.contains(resource)) {
3610  return true;
3611  }
3612  }
3613 
3614  return false;
3615 }
3616 
3617 
3618 // This matcher is used to match the task id of a `TaskStatus` message.
3619 MATCHER_P(TaskStatusTaskIdEq, taskInfo, "")
3620 {
3621  return arg.task_id() == taskInfo.task_id();
3622 }
3623 
3624 
3625 // This matcher is used to match the state of a `TaskStatus` message.
3626 MATCHER_P(TaskStatusStateEq, taskState, "")
3627 {
3628  return arg.state() == taskState;
3629 }
3630 
3631 
3632 // This matcher is used to match the task id of an `Event.update.status`
3633 // message.
3634 MATCHER_P(TaskStatusUpdateTaskIdEq, taskInfo, "")
3635 {
3636  return arg.status().task_id() == taskInfo.task_id();
3637 }
3638 
3639 
3640 // This matcher is used to match the state of an `Event.update.status`
3641 // message.
3642 MATCHER_P(TaskStatusUpdateStateEq, taskState, "")
3643 {
3644  return arg.status().state() == taskState;
3645 }
3646 
3647 
3648 // This matcher is used to match the task id of
3649 // `authorization::Request.Object.TaskInfo`.
3650 MATCHER_P(AuthorizationRequestHasTaskID, taskId, "")
3651 {
3652  if (!arg.has_object()) {
3653  return false;
3654  }
3655 
3656  if (!arg.object().has_task_info()) {
3657  return false;
3658  }
3659 
3660  return arg.object().task_info().task_id() == taskId;
3661 }
3662 
3663 
3664 // This matcher is used to match the task id of `Option<TaskInfo>`.
3665 MATCHER_P(OptionTaskHasTaskID, taskId, "")
3666 {
3667  return arg.isNone() ? false : arg->task_id() == taskId;
3668 }
3669 
3670 
3671 // This matcher is used to match an `Option<TaskGroupInfo>` which contains a
3672 // task with the specified task id.
3673 MATCHER_P(OptionTaskGroupHasTaskID, taskId, "")
3674 {
3675  if (arg.isNone()) {
3676  return false;
3677  }
3678 
3679  foreach(const TaskInfo& taskInfo, arg->tasks()) {
3680  if (taskInfo.task_id() == taskId) {
3681  return true;
3682  }
3683  }
3684 
3685  return false;
3686 }
3687 
3688 
3690 {
3691 public:
3692  struct Printer
3693  {
3694  std::string operator()(
3695  const ::testing::TestParamInfo<ParamExecutorType>& info) const
3696  {
3697  switch (info.param.type) {
3698  case COMMAND:
3699  return "CommandExecutor";
3700  case DEFAULT:
3701  return "DefaultExecutor";
3702  default:
3703  UNREACHABLE();
3704  }
3705  }
3706  };
3707 
3709  {
3710  return ParamExecutorType(COMMAND);
3711  }
3712 
3714  {
3715  return ParamExecutorType(DEFAULT);
3716  }
3717 
3718  bool isCommandExecutor() const { return type == COMMAND; }
3719  bool isDefaultExecutor() const { return type == DEFAULT; }
3720 
3721 private:
3722  enum Type
3723  {
3724  COMMAND,
3725  DEFAULT
3726  };
3727 
3728  ParamExecutorType(Type _type) : type(_type) {}
3729 
3730  Type type;
3731 };
3732 
3733 } // namespace tests {
3734 } // namespace internal {
3735 } // namespace mesos {
3736 
3737 #endif // __TESTS_MESOS_HPP__
TVolume createVolumeFromDockerImage(const std::string &containerPath, const std::string &imageName, const typename TVolume::Mode &mode)
Definition: mesos.hpp:757
TVolume createVolumeHostPath(const std::string &containerPath, const std::string &hostPath, const typename TVolume::Mode &mode, const Option< typename TMountPropagation::Mode > &mountPropagationMode=None())
Definition: mesos.hpp:730
mesos::v1::Resource createDiskResource(Args &&...args)
Definition: mesos.hpp:2002
Definition: path.hpp:26
std::string generate(const std::string &prefix="")
Returns &#39;prefix(N)&#39; where N represents the number of instances where the same prefix (wrt...
Definition: mesos.hpp:123
static constexpr uint64_t MEGABYTES
Definition: bytes.hpp:35
Future< process::Message > FutureUnionMessage(Message message, UnionType unionType, From from, To to, bool drop=false)
Definition: gmock.hpp:518
#define DEFAULT_FRAMEWORK_INFO
Definition: mesos.hpp:2299
const std::string defaultAgentResourcesString
Definition: mesos.hpp:287
constexpr const char * arg1
Definition: shell.hpp:45
static TFrameworkInfo create()
Definition: mesos.hpp:508
ContentType
Definition: http.hpp:43
Definition: capabilities.hpp:42
mesos::v1::Resource createReservedResource(Args &&...args)
Definition: mesos.hpp:1950
Try< bool > update(const std::string &link, const Handle &parent, uint16_t protocol, const action::Mirror &mirror)
DomainInfo createDomainInfo(Args &&...args)
Definition: mesos.hpp:1745
process::Owned< EndpointDetector > createEndpointDetector(const process::UPID &pid)
Definition: mesos.hpp:3196
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:121
mesos::v1::ExecutorInfo createExecutorInfo(Args &&...args)
Definition: mesos.hpp:1836
Definition: executor.hpp:147
Future< Response > request(const Request &request, bool streamedResponse=false)
Asynchronously sends an HTTP request to the process and returns the HTTP response once the entire res...
T & get()&
Definition: try.hpp:73
Definition: master.hpp:27
Definition: check.hpp:33
network::inet::Address address
Definition: pid.hpp:177
mesos::v1::Resource::ReservationInfo createDynamicReservationInfo(const std::string &role, const Option< std::string > &principal=None(), const Option< mesos::v1::Labels > &labels=None())
Definition: mesos.hpp:1939
mesos::v1::scheduler::Call createCallSubscribe(const mesos::v1::FrameworkInfo &frameworkInfo, const Option< mesos::v1::FrameworkID > &frameworkId=None())
Definition: mesos.hpp:2259
void events(std::queue< Event > events)
Definition: mesos.hpp:2990
void DropHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3489
mesos::v1::TaskInfo createTask(Args &&...args)
Definition: mesos.hpp:1909
MesosTest(const Option< zookeeper::URL > &url=None())
virtual Try< process::Owned< cluster::Master > > StartMaster(const Option< master::Flags > &flags=None())
mesos::v1::executor::Event Event
Definition: mesos.hpp:2846
mesos::v1::resource_provider::Event Event
Definition: mesos.hpp:3226
void ExpectNoFutureUnionMessages(Message message, UnionType unionType, From from, To to)
Definition: gmock.hpp:675
Definition: message.hpp:22
void setAgentID(mesos::v1::TaskInfo *task, const mesos::v1::AgentID &agentId)
Definition: mesos.hpp:819
Result< std::string > user(Option< uid_t > uid=None())
Definition: su.hpp:284
Result< ProcessStatus > status(pid_t pid)
Definition: proc.hpp:166
mesos::v1::NetworkInfo createNetworkInfo(Args &&...args)
Definition: mesos.hpp:1890
const std::string defaultTaskResourcesString
Definition: mesos.hpp:295
Definition: uuid.hpp:33
mesos::v1::Volume createVolumeHostPath(Args &&...args)
Definition: mesos.hpp:1873
mesos::v1::Offer::Operation SHRINK_VOLUME(Args &&...args)
Definition: mesos.hpp:2089
virtual Status launchTasks(const std::vector< OfferID > &offerIds, const std::vector< TaskInfo > &tasks, const Filters &filters=Filters())=0
mesos::v1::Offer::Operation CREATE_DISK(Args &&...args)
Definition: mesos.hpp:2115
mesos::v1::scheduler::Call Call
Definition: mesos.hpp:2641
Definition: resources.hpp:81
mesos::v1::Offer::Operation RESERVE(Args &&...args)
Definition: mesos.hpp:2047
ResourceProviderInfo info
Definition: mesos.hpp:3189
Definition: scheduler.hpp:349
std::string encode(const std::string &s)
Encode a string to Base64 with the standard Base64 alphabet.
Definition: base64.hpp:170
bool isCommandExecutor() const
Definition: mesos.hpp:3718
mesos::v1::ContainerInfo createContainerInfo(const Option< std::string > &imageName=None(), const std::vector< mesos::v1::Volume > &volumes={})
Definition: mesos.hpp:1898
Definition: lambda.hpp:30
void DropUnionHttpRequests(Message message, UnionType unionType, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:602
Definition: scheduler.hpp:70
Operation
Definition: cgroups.hpp:458
mesos::v1::Resource::DiskInfo::Source createDiskSourceMount(Args &&...args)
Definition: mesos.hpp:1975
Definition: flags.hpp:39
T _FutureProtobuf(const process::Message &message)
Definition: mesos.hpp:3460
mesos::v1::Offer::Operation DESTROY_DISK(Args &&...args)
Definition: mesos.hpp:2126
mesos::v1::CommandInfo createCommandInfo(const Option< std::string > &value=None(), const std::vector< std::string > &arguments={})
Definition: mesos.hpp:1848
TResource createReservedResource(const std::string &name, const std::string &value, const TReservationInfos &...reservations)
Definition: mesos.hpp:977
mesos::slave::ContainerConfig createContainerConfig(const CommandInfo &commandInfo, const std::string &resources, const std::string &sandboxDirectory, const Option< ContainerInfo > &containerInfo=None(), const Option< std::string > &user=None())
Definition: mesos.hpp:1550
void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
Definition: mesos.hpp:3479
bool isSome() const
Definition: option.hpp:115
Definition: http.hpp:520
Creates a VALUE-type secret containing a JWT.
Definition: jwt_secret_generator.hpp:36
constexpr const char * arg0
Definition: shell.hpp:44
mesos::v1::scheduler::Call createCallAcknowledgeOperationStatus(const mesos::v1::FrameworkID &frameworkId, const mesos::v1::AgentID &agentId, const mesos::v1::ResourceProviderID &resourceProviderId, const mesos::v1::scheduler::Event::UpdateOperationStatus &update)
Definition: mesos.hpp:2188
TResource::ReservationInfo createDynamicReservationInfo(const std::string &role, const Option< std::string > &principal=None(), const Option< TLabels > &labels=None())
Definition: mesos.hpp:951
virtual Try< process::Owned< cluster::Slave > > StartSlave(mesos::master::detector::MasterDetector *detector, const Option< slave::Flags > &flags=None(), bool mock=false)
TContainerInfo createContainerInfo(const Option< std::string > &imageName=None(), const std::vector< TVolume > &volumes={})
Definition: mesos.hpp:781
mesos::v1::scheduler::Event Event
Definition: mesos.hpp:2642
mesos::v1::Volume createVolumeSandboxPath(Args &&...args)
Definition: mesos.hpp:1865
static Try< Resource > parse(const std::string &name, const std::string &value, const std::string &role)
Returns a Resource with the given name, value, and role.
Resource provider driver.
Definition: resource_provider.hpp:56
void DropHttpRequests(Message message, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:581
mesos::v1::Resource::DiskInfo::Source createDiskSourcePath(Args &&...args)
Definition: mesos.hpp:1966
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector, const FrameworkInfo &framework, bool implicitAcknowledgements, const Credential &credential)
Definition: mesos.hpp:2486
Definition: resource_estimator.hpp:37
Environment * environment
process::Future< Message > FutureUnionHttp(Message message, UnionType unionType, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3438
std::vector< std::string > tokenize(const std::string &s, const std::string &delims, const Option< size_t > &maxTokens=None())
Definition: strings.hpp:139
This interface is used to enable an identity service or any other back end to check authorization pol...
Definition: authorizer.hpp:243
TExecutorInfo createExecutorInfo(const TExecutorID &executorId, const Option< TCommandInfo > &command, const Option< TResources > &resources, const Option< typename TExecutorInfo::Type > &type, const Option< TFrameworkID > &frameworkId)
Definition: mesos.hpp:573
mesos::v1::Resource::DiskInfo::Source createDiskSourceRaw(Args &&...args)
Definition: mesos.hpp:1993
mesos::v1::scheduler::APIResult APIResult
Definition: mesos.hpp:2640
Definition: scheduler.hpp:185
mesos::v1::TaskGroupInfo createTaskGroupInfo(const std::vector< mesos::v1::TaskInfo > &tasks)
Definition: mesos.hpp:1923
#define CHECK_SOME(expression)
Definition: check.hpp:50
mesos::v1::Resource::ReservationInfo createStaticReservationInfo(const std::string &role)
Definition: mesos.hpp:1932
Definition: containerizer.hpp:59
static UUID random()
Definition: uuid.hpp:38
Resources pushReservation(const Resource::ReservationInfo &reservation) const
void DropUnionMessages(Message message, UnionType unionType, From from, To to)
Definition: gmock.hpp:569
An "untyped" PID, used to encapsulate the process ID for lower-layer abstractions (eg...
Definition: pid.hpp:39
Definition: http.hpp:129
const ExecutorID id
Definition: mesos.hpp:2445
#define AWAIT_READY(actual)
Definition: gtest.hpp:282
process::PID< master::Master > launch(const Flags &flags, mesos::allocator::Allocator *_allocator=nullptr)
Try< std::vector< Info > > infos(int familiy, int states)
mesos::v1::Offer::Operation UNRESERVE(Args &&...args)
Definition: mesos.hpp:2057
void events(Mesos *mesos, std::queue< Event > events)
Definition: mesos.hpp:2534
mesos::v1::Image createDockerImage(Args &&...args)
Definition: mesos.hpp:1857
Result< std::vector< Filter< Classifier > > > filters(const std::string &_link, const Handle &parent)
Definition: internal.hpp:769
mesos::v1::Volume createVolumeFromDockerImage(Args &&...args)
Definition: mesos.hpp:1882
void SetUp() override
Definition: utils.hpp:37
#define DEFAULT_CREDENTIAL
Definition: mesos.hpp:2295
Represents a POSIX or Windows file system path and offers common path manipulations.
Definition: path.hpp:202
constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[]
Definition: mesos.hpp:109
virtual slave::Flags CreateSlaveFlags()
Try< long > cpus()
Definition: os.hpp:286
void ExpectNoFutureUnionProtobufs(Message message, UnionType unionType, From from, To to)
Definition: mesos.hpp:3534
Definition: agent.hpp:27
TTaskInfo createTask(const TSlaveID &slaveId, const TResources &resources, const TCommandInfo &command, const Option< TExecutorID > &executorId=None(), const std::string &name="test-task", const std::string &id=id::UUID::random().toString())
Definition: mesos.hpp:837
Definition: spec.hpp:26
constexpr char READONLY_HTTP_AUTHENTICATION_REALM[]
Definition: mesos.hpp:108
mesos::v1::Offer::Operation DESTROY(Args &&...args)
Definition: mesos.hpp:2073
virtual Status declineOffer(const OfferID &offerId, const Filters &filters=Filters())=0
uint16_t port
Definition: address.hpp:134
static Option< T > none()
Definition: option.hpp:31
Definition: http.hpp:458
constexpr char DEFAULT_TEST_ROLE[]
Definition: mesos.hpp:110
TOffer::Operation RESERVE(const TResources &resources, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1314
std::string operator()(const ::testing::TestParamInfo< ParamExecutorType > &info) const
Definition: mesos.hpp:3694
Resources toUnreserved() const
Try< ImageManifest > parse(const std::string &value)
Definition: parse.hpp:36
void DropProtobufs(T t, From from, To to)
Definition: mesos.hpp:3469
mesos::v1::scheduler::Call createCallReconcileOperations(const mesos::v1::FrameworkID &frameworkId, const std::vector< mesos::v1::scheduler::Call::ReconcileOperations::Operation > &operations={})
Definition: mesos.hpp:2235
const T & get() const &
Definition: option.hpp:118
process::http::Headers createBasicAuthHeaders(Args &&...args)
Definition: mesos.hpp:2022
Definition: resources.hpp:81
process::Future< Secret > generate(const process::http::authentication::Principal &principal) override
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
static ParamExecutorType defaultExecutor()
Definition: mesos.hpp:3713
The SecretGenerator interface represents a mechanism to create a secret from a principal.
Definition: secret_generator.hpp:34
const int UNKNOWN
Definition: diagnosis.hpp:39
Try< int_fd > accept(int_fd s)
Definition: network.hpp:31
Definition: scheduler.hpp:69
static Try< URL > parse(const std::string &url)
Definition: url.hpp:75
Definition: executor.hpp:75
process::Future< Message > FutureHttp(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3418
mesos::v1::Parameters parameterize(Args &&...args)
Definition: mesos.hpp:2134
Definition: executor.hpp:55
mesos::v1::resource_provider::Call Call
Definition: mesos.hpp:3225
bool isDefaultExecutor() const
Definition: mesos.hpp:3719
mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(Args &&...args)
Definition: mesos.hpp:1984
TestMesos(const std::string &master, ContentType contentType, const std::shared_ptr< MockHTTPScheduler< Mesos, Event >> &scheduler, const Option< std::shared_ptr< mesos::master::detector::MasterDetector >> &detector=None())
Definition: mesos.hpp:2589
JSON::Proxy jsonify(const T &)
Definition: jsonify.hpp:701
#define UNREACHABLE()
Definition: unreachable.hpp:22
static ParamExecutorType commandExecutor()
Definition: mesos.hpp:3708
Basic model of an allocator: resources are allocated to a framework in the form of offers...
Definition: allocator.hpp:70
mesos::v1::executor::Call Call
Definition: mesos.hpp:2845
Future< Message > FutureMessage(Name name, From from, To to, bool drop=false)
Definition: gmock.hpp:499
void events(Mesos *mesos, std::queue< Event > events)
Definition: mesos.hpp:2772
void operationDefault(const typename Event::ApplyOperation &operation)
Definition: mesos.hpp:3098
void ExpectNoFutureUnionHttpRequests(Message message, UnionType unionType, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:643
Iterable< V > map(F &&f, const Iterable< U, Us... > &input)
Definition: lambda.hpp:46
Definition: protobuf.hpp:797
#define flags
Definition: decoder.hpp:18
process::Future< Message > FutureUnionProtobuf(Message message, UnionType unionType, From from, To to, bool drop=false)
Definition: mesos.hpp:3406
void start(process::Owned< mesos::internal::EndpointDetector > detector, ContentType contentType)
Definition: mesos.hpp:3027
URI image(const std::string &repository, const std::string &reference, const std::string &registry, const Option< std::string > &scheme=None(), const Option< int > &port=None())
Definition: docker.hpp:30
Definition: none.hpp:27
Definition: attributes.hpp:24
Contains information associated with an authenticated principal.
Definition: authenticator.hpp:41
process::Future< Nothing > send(const Call &call)
Definition: mesos.hpp:3022
void ExpectNoFutureMessages(Name name, From from, To to)
Definition: gmock.hpp:663
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector, const FrameworkInfo &framework, bool implicitAcknowledgements=true)
Definition: mesos.hpp:2468
static void settle()
std::string error(const std::string &msg, uint32_t code)
void ExpectNoFutureUnionHttpProtobufs(Message message, UnionType unionType, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3562
void ExpectNoFutureHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3545
Type
Definition: capabilities.hpp:79
mesos::v1::scheduler::Call createCallKill(const mesos::v1::FrameworkID &frameworkId, const mesos::v1::TaskID &taskId, const Option< mesos::v1::AgentID > &agentId=None(), const Option< mesos::v1::KillPolicy > &killPolicy=None())
Definition: mesos.hpp:2210
mesos::v1::Offer::Operation CREATE(Args &&...args)
Definition: mesos.hpp:2065
MockResourceProvider(const ResourceProviderInfo &_info, const Option< Resources > &_resources=None())
Definition: mesos.hpp:2948
std::string body
Definition: http.hpp:565
uint64_t bytes() const
Definition: bytes.hpp:79
Definition: mesos.hpp:3246
TResource createPersistentVolume(const Bytes &size, const std::string &role, const std::string &persistenceId, const std::string &containerPath, const Option< std::string > &reservationPrincipal=None(), const Option< typename TResource::DiskInfo::Source > &source=None(), const Option< std::string > &creatorPrincipal=None(), bool isShared=false)
Definition: mesos.hpp:1168
void publishDefault(const typename Event::PublishResources &publish)
Definition: mesos.hpp:3171
std::string body
Definition: message.hpp:27
Future< http::Request > FutureUnionHttpRequest(Message message, UnionType unionType, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:473
Option< zookeeper::URL > zookeeperUrl
Definition: mesos.hpp:274
An abstraction of a Master detector which can be used to detect the leading master from a group...
Definition: detector.hpp:38
TestMesos(ContentType contentType, const std::shared_ptr< MockHTTPExecutor< Mesos, Event >> &executor, const std::map< std::string, std::string > &environment)
Definition: mesos.hpp:2818
ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
Definition: mesos.hpp:2891
Try< uint32_t > type(const std::string &path)
Definition: gtest.hpp:63
TResource createDiskResource(const std::string &value, const std::string &role, const Option< std::string > &persistenceID, const Option< std::string > &containerPath, const Option< typename TResource::DiskInfo::Source > &source=None(), bool isShared=false)
Definition: mesos.hpp:1137
TOffer::Operation LAUNCH_GROUP(const TExecutorInfo &executorInfo, const TTaskGroupInfo &taskGroup)
Definition: mesos.hpp:1401
Try< mode_t > mode(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:159
ACTION_P5(LaunchTasks, executor, tasks, cpus, mem, role)
Definition: mesos.hpp:2338
static TCredential create()
Definition: mesos.hpp:495
void allocate(const std::string &role)
void ExpectNoFutureProtobufs(T t, From from, To to)
Definition: mesos.hpp:3524
process::Future< T > FutureProtobuf(T t, From from, To to, bool drop=false)
Definition: mesos.hpp:3395
hashmap< std::string, double > convertToHashmap(Args &&...args)
Definition: mesos.hpp:2039
bool enabled()
TTaskGroupInfo createTaskGroupInfo(const std::vector< TTaskInfo > &tasks)
Definition: mesos.hpp:929
Option< Resources > find(const Resources &targets) const
constexpr int FAILURE
Definition: decoder.hpp:50
Definition: mesos.hpp:2427
Try< Nothing > kill(const std::string &hierarchy, const std::string &cgroup, int signal)
void subscribedDefault(const typename Event::Subscribed &subscribed)
Definition: mesos.hpp:3073
mesos::v1::Offer::Operation LAUNCH(const std::vector< mesos::v1::TaskInfo > &tasks)
Definition: mesos.hpp:2097
Try< Nothing > bind(int_fd s, const Address &address)
Definition: network.hpp:46
struct process::UPID::ID id
mesos::v1::Resource createPersistentVolume(Args &&...args)
Definition: mesos.hpp:2012
Definition: qos_controller.hpp:44
mesos::v1::scheduler::Call createCallAccept(const mesos::v1::FrameworkID &frameworkId, const mesos::v1::Offer &offer, const std::vector< mesos::v1::Offer::Operation > &operations, const Option< mesos::v1::Filters > &filters=None())
Definition: mesos.hpp:2141
Definition: zookeeper_test_server.hpp:36
ACTION_P2(InvokeRecoverResourcesWithFilters, allocator, timeout)
Definition: allocator.hpp:182
google::protobuf::RepeatedPtrField< mesos::v1::WeightInfo > createWeightInfos(Args &&...args)
Definition: mesos.hpp:2031
mesos::v1::scheduler::Response Response
Definition: mesos.hpp:2644
static void pause()
Pauses the clock e.g.
Definition: bytes.hpp:30
#define ASSERT_SOME(actual)
Definition: gtest.hpp:128
constexpr char DEFAULT_JWT_SECRET_KEY[]
Definition: mesos.hpp:111
static void resume()
std::string stringify(int flags)
net::IP ip
Definition: address.hpp:133
TOffer::Operation CREATE_DISK(const TResource &source, const TTargetType &targetType, const Option< std::string > &targetProfile=None(), const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1418
~TestMesos() override
Definition: mesos.hpp:2611
bool contains(const Resources &that) const
ACTION_P(InvokeInitialize, allocator)
Definition: allocator.hpp:56
mesos::v1::Offer::Operation LAUNCH_GROUP(Args &&...args)
Definition: mesos.hpp:2105
mesos::v1::AgentID getAgentID(const mesos::v1::Offer &offer)
Definition: mesos.hpp:807
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector)
Definition: mesos.hpp:2452
mesos::v1::Offer::Operation GROW_VOLUME(Args &&...args)
Definition: mesos.hpp:2081
static bool paused()
Check whether clock is currently running.
Definition: parse.hpp:33
static TCredential create()
Definition: mesos.hpp:481
void ExpectNoFutureHttpRequests(Message message, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:622
ACTION(DeclineOffers)
Definition: mesos.hpp:2389
Future< http::Request > FutureHttpRequest(Message message, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:445
constexpr const char * name
Definition: shell.hpp:43
void DropUnionHttpProtobufs(Message message, UnionType unionType, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3506
mesos::v1::Resource::DiskInfo createDiskInfo(Args &&...args)
Definition: mesos.hpp:1958
void TearDown() override
Definition: utils.hpp:44
mesos::v1::executor::Mesos Mesos
Definition: mesos.hpp:2847
mesos::v1::scheduler::Call createCallAcknowledge(const mesos::v1::FrameworkID &frameworkId, const mesos::v1::AgentID &agentId, const mesos::v1::scheduler::Event::Update &update)
Definition: mesos.hpp:2166
Try< std::set< std::string > > subsystems()
Definition: mesos.hpp:2306
void filter(Filter *filter)
virtual master::Flags CreateMasterFlags()
MATCHER_P(OffersHaveAnyResource, filter,"")
Definition: mesos.hpp:3582
void DropMessages(Name name, From from, To to)
Definition: gmock.hpp:557
mesos::Environment createEnvironment(const hashmap< std::string, std::string > &map)
Definition: mesos.hpp:2278