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