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::Mode& mode,
862  const typename TVolume::Source::CSIVolume::VolumeCapability
863  ::AccessMode::Mode& accessMode)
864 {
865  TVolume volume;
866  volume.set_container_path(containerPath);
867  volume.set_mode(mode);
868 
869  typename TVolume::Source* source = volume.mutable_source();
870  source->set_type(TVolume::Source::CSI_VOLUME);
871  source->mutable_csi_volume()->set_plugin_name(pluginName);
872 
873  typename TVolume::Source::CSIVolume::StaticProvisioning* staticInfo =
874  source->mutable_csi_volume()->mutable_static_provisioning();
875 
876  staticInfo->set_volume_id(volumeId);
877  staticInfo->mutable_volume_capability()->mutable_mount();
878  staticInfo->mutable_volume_capability()
879  ->mutable_access_mode()->set_mode(accessMode);
880 
881  return volume;
882 }
883 
884 
885 template <typename TNetworkInfo>
886 inline TNetworkInfo createNetworkInfo(
887  const std::string& networkName)
888 {
889  TNetworkInfo info;
890  info.set_name(networkName);
891  return info;
892 }
893 
894 
895 template <typename TContainerInfo, typename TVolume, typename TImage>
896 inline TContainerInfo createContainerInfo(
897  const Option<std::string>& imageName = None(),
898  const std::vector<TVolume>& volumes = {})
899 {
900  TContainerInfo info;
901  info.set_type(TContainerInfo::MESOS);
902 
903  if (imageName.isSome()) {
904  TImage* image = info.mutable_mesos()->mutable_image();
905  image->CopyFrom(createDockerImage<TImage>(imageName.get()));
906  }
907 
908  foreach (const TVolume& volume, volumes) {
909  info.add_volumes()->CopyFrom(volume);
910  }
911 
912  return info;
913 }
914 
915 
916 inline SlaveID getAgentID(const Offer& offer)
917 {
918  return offer.slave_id();
919 }
920 
921 
922 inline mesos::v1::AgentID getAgentID(const mesos::v1::Offer& offer)
923 {
924  return offer.agent_id();
925 }
926 
927 
928 inline void setAgentID(TaskInfo* task, const SlaveID& slaveId)
929 {
930  task->mutable_slave_id()->CopyFrom(slaveId);
931 }
932 
933 
934 inline void setAgentID(
935  mesos::v1::TaskInfo* task,
936  const mesos::v1::AgentID& agentId)
937 {
938  task->mutable_agent_id()->CopyFrom(agentId);
939 }
940 
941 
942 // TODO(bmahler): Refactor this to make the distinction between
943 // command tasks and executor tasks clearer.
944 template <
945  typename TTaskInfo,
946  typename TExecutorID,
947  typename TSlaveID,
948  typename TResources,
949  typename TExecutorInfo,
950  typename TCommandInfo,
951  typename TOffer,
952  typename TScalar>
953 inline TTaskInfo createTask(
954  const TSlaveID& slaveId,
955  const TResources& resourceRequests,
956  const TCommandInfo& command,
957  const Option<TExecutorID>& executorId = None(),
958  const std::string& name = "test-task",
959  const std::string& id = id::UUID::random().toString(),
960  const google::protobuf::Map<std::string, TScalar>& resourceLimits = {})
961 {
962  TTaskInfo task;
963  task.set_name(name);
964  task.mutable_task_id()->set_value(id);
965  setAgentID(&task, slaveId);
966  task.mutable_resources()->CopyFrom(resourceRequests);
967  if (!resourceLimits.empty()) {
968  *task.mutable_limits() = resourceLimits;
969  }
970  if (executorId.isSome()) {
971  TExecutorInfo executor;
972  executor.mutable_executor_id()->CopyFrom(executorId.get());
973  executor.mutable_command()->CopyFrom(command);
974  task.mutable_executor()->CopyFrom(executor);
975  } else {
976  task.mutable_command()->CopyFrom(command);
977  }
978 
979  return task;
980 }
981 
982 
983 template <
984  typename TTaskInfo,
985  typename TExecutorID,
986  typename TSlaveID,
987  typename TResources,
988  typename TExecutorInfo,
989  typename TCommandInfo,
990  typename TOffer,
991  typename TScalar>
992 inline TTaskInfo createTask(
993  const TSlaveID& slaveId,
994  const TResources& resourceRequests,
995  const std::string& command,
996  const Option<TExecutorID>& executorId = None(),
997  const std::string& name = "test-task",
998  const std::string& id = id::UUID::random().toString(),
999  const google::protobuf::Map<std::string, TScalar>& resourceLimits = {})
1000 {
1001  return createTask<
1002  TTaskInfo,
1003  TExecutorID,
1004  TSlaveID,
1005  TResources,
1006  TExecutorInfo,
1007  TCommandInfo,
1008  TOffer,
1009  TScalar>(
1010  slaveId,
1011  resourceRequests,
1012  createCommandInfo<TCommandInfo>(command),
1013  executorId,
1014  name,
1015  id,
1016  resourceLimits);
1017 }
1018 
1019 
1020 template <
1021  typename TTaskInfo,
1022  typename TExecutorID,
1023  typename TSlaveID,
1024  typename TResources,
1025  typename TExecutorInfo,
1026  typename TCommandInfo,
1027  typename TOffer,
1028  typename TScalar>
1029 inline TTaskInfo createTask(
1030  const TOffer& offer,
1031  const std::string& command,
1032  const Option<TExecutorID>& executorId = None(),
1033  const std::string& name = "test-task",
1034  const std::string& id = id::UUID::random().toString(),
1035  const google::protobuf::Map<std::string, TScalar>& resourceLimits = {})
1036 {
1037  return createTask<
1038  TTaskInfo,
1039  TExecutorID,
1040  TSlaveID,
1041  TResources,
1042  TExecutorInfo,
1043  TCommandInfo,
1044  TOffer,
1045  TScalar>(
1046  getAgentID(offer),
1047  offer.resources(),
1048  command,
1049  executorId,
1050  name,
1051  id,
1052  resourceLimits);
1053 }
1054 
1055 
1056 template <typename TTaskGroupInfo, typename TTaskInfo>
1057 inline TTaskGroupInfo createTaskGroupInfo(const std::vector<TTaskInfo>& tasks)
1058 {
1059  TTaskGroupInfo taskGroup;
1060  foreach (const TTaskInfo& task, tasks) {
1061  taskGroup.add_tasks()->CopyFrom(task);
1062  }
1063  return taskGroup;
1064 }
1065 
1066 
1067 template <typename TResource>
1068 inline typename TResource::ReservationInfo createStaticReservationInfo(
1069  const std::string& role)
1070 {
1071  typename TResource::ReservationInfo info;
1072  info.set_type(TResource::ReservationInfo::STATIC);
1073  info.set_role(role);
1074  return info;
1075 }
1076 
1077 
1078 template <typename TResource, typename TLabels>
1079 inline typename TResource::ReservationInfo createDynamicReservationInfo(
1080  const std::string& role,
1081  const Option<std::string>& principal = None(),
1082  const Option<TLabels>& labels = None())
1083 {
1084  typename TResource::ReservationInfo info;
1085 
1086  info.set_type(TResource::ReservationInfo::DYNAMIC);
1087  info.set_role(role);
1088 
1089  if (principal.isSome()) {
1090  info.set_principal(principal.get());
1091  }
1092 
1093  if (labels.isSome()) {
1094  info.mutable_labels()->CopyFrom(labels.get());
1095  }
1096 
1097  return info;
1098 }
1099 
1100 
1101 template <
1102  typename TResource,
1103  typename TResources,
1104  typename... TReservationInfos>
1105 inline TResource createReservedResource(
1106  const std::string& name,
1107  const std::string& value,
1108  const TReservationInfos&... reservations)
1109 {
1110  std::initializer_list<typename TResource::ReservationInfo> reservations_ = {
1111  reservations...
1112  };
1113 
1114  TResource resource = TResources::parse(name, value, "*").get();
1115  resource.mutable_reservations()->CopyFrom(
1116  google::protobuf::RepeatedPtrField<typename TResource::ReservationInfo>{
1117  reservations_.begin(), reservations_.end()});
1118 
1119  return resource;
1120 }
1121 
1122 
1123 // NOTE: We only set the volume in DiskInfo if 'containerPath' is set.
1124 // If volume mode is not specified, Volume::RW will be used (assuming
1125 // 'containerPath' is set).
1126 template <typename TResource, typename TVolume>
1127 inline typename TResource::DiskInfo createDiskInfo(
1128  const Option<std::string>& persistenceId,
1129  const Option<std::string>& containerPath,
1130  const Option<typename TVolume::Mode>& mode = None(),
1131  const Option<std::string>& hostPath = None(),
1133  const Option<std::string>& principal = None())
1134 {
1135  typename TResource::DiskInfo info;
1136 
1137  if (persistenceId.isSome()) {
1138  info.mutable_persistence()->set_id(persistenceId.get());
1139  }
1140 
1141  if (principal.isSome()) {
1142  info.mutable_persistence()->set_principal(principal.get());
1143  }
1144 
1145  if (containerPath.isSome()) {
1146  TVolume volume;
1147  volume.set_container_path(containerPath.get());
1148  volume.set_mode(mode.isSome() ? mode.get() : TVolume::RW);
1149 
1150  if (hostPath.isSome()) {
1151  volume.set_host_path(hostPath.get());
1152  }
1153 
1154  info.mutable_volume()->CopyFrom(volume);
1155  }
1156 
1157  if (source.isSome()) {
1158  info.mutable_source()->CopyFrom(source.get());
1159  }
1160 
1161  return info;
1162 }
1163 
1164 
1165 // Helper for creating a disk source with type `PATH`.
1166 template <typename TResource>
1167 inline typename TResource::DiskInfo::Source createDiskSourcePath(
1168  const Option<std::string>& root = None(),
1169  const Option<std::string>& id = None(),
1170  const Option<std::string>& profile = None())
1171 {
1172  typename TResource::DiskInfo::Source source;
1173 
1174  source.set_type(TResource::DiskInfo::Source::PATH);
1175 
1176  if (root.isSome()) {
1177  source.mutable_path()->set_root(root.get());
1178  }
1179 
1180  if (id.isSome()) {
1181  source.set_id(id.get());
1182  }
1183 
1184  if (profile.isSome()) {
1185  source.set_profile(profile.get());
1186  }
1187 
1188  return source;
1189 }
1190 
1191 
1192 // Helper for creating a disk source with type `MOUNT`.
1193 template <typename TResource>
1194 inline typename TResource::DiskInfo::Source createDiskSourceMount(
1195  const Option<std::string>& root = None(),
1196  const Option<std::string>& id = None(),
1197  const Option<std::string>& profile = None())
1198 {
1199  typename TResource::DiskInfo::Source source;
1200 
1201  source.set_type(TResource::DiskInfo::Source::MOUNT);
1202 
1203  if (root.isSome()) {
1204  source.mutable_mount()->set_root(root.get());
1205  }
1206 
1207  if (id.isSome()) {
1208  source.set_id(id.get());
1209  }
1210 
1211  if (profile.isSome()) {
1212  source.set_profile(profile.get());
1213  }
1214 
1215  return source;
1216 }
1217 
1218 
1219 // Helper for creating a disk source with type `BLOCK'
1220 template <typename TResource>
1221 inline typename TResource::DiskInfo::Source createDiskSourceBlock(
1222  const Option<std::string>& id = None(),
1223  const Option<std::string>& profile = None())
1224 {
1225  typename TResource::DiskInfo::Source source;
1226 
1227  source.set_type(TResource::DiskInfo::Source::BLOCK);
1228 
1229  if (id.isSome()) {
1230  source.set_id(id.get());
1231  }
1232 
1233  if (profile.isSome()) {
1234  source.set_profile(profile.get());
1235  }
1236 
1237  return source;
1238 }
1239 
1240 
1241 // Helper for creating a disk source with type `RAW'.
1242 template <typename TResource>
1243 inline typename TResource::DiskInfo::Source createDiskSourceRaw(
1244  const Option<std::string>& id = None(),
1245  const Option<std::string>& profile = None())
1246 {
1247  typename TResource::DiskInfo::Source source;
1248 
1249  source.set_type(TResource::DiskInfo::Source::RAW);
1250 
1251  if (id.isSome()) {
1252  source.set_id(id.get());
1253  }
1254 
1255  if (profile.isSome()) {
1256  source.set_profile(profile.get());
1257  }
1258 
1259  return source;
1260 }
1261 
1262 
1263 // Helper for creating a disk resource.
1264 template <typename TResource, typename TResources, typename TVolume>
1265 inline TResource createDiskResource(
1266  const std::string& value,
1267  const std::string& role,
1268  const Option<std::string>& persistenceID,
1269  const Option<std::string>& containerPath,
1271  bool isShared = false)
1272 {
1273  TResource resource = TResources::parse("disk", value, role).get();
1274 
1275  if (persistenceID.isSome() || containerPath.isSome() || source.isSome()) {
1276  resource.mutable_disk()->CopyFrom(
1277  createDiskInfo<TResource, TVolume>(
1278  persistenceID,
1279  containerPath,
1280  None(),
1281  None(),
1282  source));
1283 
1284  if (isShared) {
1285  resource.mutable_shared();
1286  }
1287  }
1288 
1289  return resource;
1290 }
1291 
1292 
1293 // Note that `reservationPrincipal` should be specified if and only if
1294 // the volume uses dynamically reserved resources.
1295 template <typename TResource, typename TResources, typename TVolume>
1296 inline TResource createPersistentVolume(
1297  const Bytes& size,
1298  const std::string& role,
1299  const std::string& persistenceId,
1300  const std::string& containerPath,
1301  const Option<std::string>& reservationPrincipal = None(),
1303  const Option<std::string>& creatorPrincipal = None(),
1304  bool isShared = false)
1305 {
1306  TResource volume = TResources::parse(
1307  "disk",
1308  stringify((double) size.bytes() / Bytes::MEGABYTES),
1309  role).get();
1310 
1311  volume.mutable_disk()->CopyFrom(
1312  createDiskInfo<TResource, TVolume>(
1313  persistenceId,
1314  containerPath,
1315  None(),
1316  None(),
1317  source,
1318  creatorPrincipal));
1319 
1320  if (reservationPrincipal.isSome()) {
1321  typename TResource::ReservationInfo& reservation =
1322  *volume.mutable_reservations()->rbegin();
1323 
1324  reservation.set_type(TResource::ReservationInfo::DYNAMIC);
1325  reservation.set_principal(reservationPrincipal.get());
1326  }
1327 
1328  if (isShared) {
1329  volume.mutable_shared();
1330  }
1331 
1332  return volume;
1333 }
1334 
1335 
1336 // Note that `reservationPrincipal` should be specified if and only if
1337 // the volume uses dynamically reserved resources.
1338 template <typename TResource, typename TResources, typename TVolume>
1339 inline TResource createPersistentVolume(
1340  TResource volume,
1341  const std::string& persistenceId,
1342  const std::string& containerPath,
1343  const Option<std::string>& reservationPrincipal = None(),
1344  const Option<std::string>& creatorPrincipal = None(),
1345  bool isShared = false)
1346 {
1348  if (volume.has_disk() && volume.disk().has_source()) {
1349  source = volume.disk().source();
1350  }
1351 
1352  volume.mutable_disk()->CopyFrom(
1353  createDiskInfo<TResource, TVolume>(
1354  persistenceId,
1355  containerPath,
1356  None(),
1357  None(),
1358  source,
1359  creatorPrincipal));
1360 
1361  if (reservationPrincipal.isSome()) {
1362  typename TResource::ReservationInfo& reservation =
1363  *volume.mutable_reservations()->rbegin();
1364 
1365  reservation.set_type(TResource::ReservationInfo::DYNAMIC);
1366  reservation.set_principal(reservationPrincipal.get());
1367  }
1368 
1369  if (isShared) {
1370  volume.mutable_shared();
1371  }
1372 
1373  return volume;
1374 }
1375 
1376 
1377 template <typename TCredential>
1379  const TCredential& credential)
1380 {
1381  return process::http::Headers({{
1382  "Authorization",
1383  "Basic " +
1384  base64::encode(credential.principal() + ":" + credential.secret())
1385  }});
1386 }
1387 
1388 
1389 // Create WeightInfos from the specified weights flag.
1390 template <typename TWeightInfo>
1391 inline google::protobuf::RepeatedPtrField<TWeightInfo> createWeightInfos(
1392  const std::string& weightsFlag)
1393 {
1394  google::protobuf::RepeatedPtrField<TWeightInfo> infos;
1395  std::vector<std::string> tokens = strings::tokenize(weightsFlag, ",");
1396  foreach (const std::string& token, tokens) {
1397  std::vector<std::string> pair = strings::tokenize(token, "=");
1398  EXPECT_EQ(2u, pair.size());
1399  double weight = atof(pair[1].c_str());
1400  TWeightInfo weightInfo;
1401  weightInfo.set_role(pair[0]);
1402  weightInfo.set_weight(weight);
1403  infos.Add()->CopyFrom(weightInfo);
1404  }
1405 
1406  return infos;
1407 }
1408 
1409 
1410 // Convert WeightInfos protobuf to weights hashmap.
1411 template <typename TWeightInfo>
1413  const google::protobuf::RepeatedPtrField<TWeightInfo> weightInfos)
1414 {
1416 
1417  foreach (const TWeightInfo& weightInfo, weightInfos) {
1418  weights[weightInfo.role()] = weightInfo.weight();
1419  }
1420 
1421  return weights;
1422 }
1423 
1424 
1425 // Helper to create DomainInfo.
1426 template <typename TDomainInfo>
1427 inline TDomainInfo createDomainInfo(
1428  const std::string& regionName,
1429  const std::string& zoneName)
1430 {
1431  TDomainInfo domain;
1432 
1433  domain.mutable_fault_domain()->mutable_region()->set_name(regionName);
1434  domain.mutable_fault_domain()->mutable_zone()->set_name(zoneName);
1435 
1436  return domain;
1437 }
1438 
1439 
1440 // Helpers for creating operations.
1441 template <typename TResources, typename TOperationID, typename TOffer>
1442 inline typename TOffer::Operation RESERVE(
1443  const TResources& resources,
1444  const Option<TOperationID>& operationId = None())
1445 {
1446  typename TOffer::Operation operation;
1447  operation.set_type(TOffer::Operation::RESERVE);
1448  operation.mutable_reserve()->mutable_resources()->CopyFrom(resources);
1449 
1450  if (operationId.isSome()) {
1451  *operation.mutable_id() = operationId.get();
1452  }
1453 
1454  return operation;
1455 }
1456 
1457 
1458 template <typename TResources, typename TOperationID, typename TOffer>
1460  const TResources& resources,
1461  const Option<TOperationID>& operationId = None())
1462 {
1463  typename TOffer::Operation operation;
1464  operation.set_type(TOffer::Operation::UNRESERVE);
1465  operation.mutable_unreserve()->mutable_resources()->CopyFrom(resources);
1466 
1467  if (operationId.isSome()) {
1468  *operation.mutable_id() = operationId.get();
1469  }
1470 
1471  return operation;
1472 }
1473 
1474 
1475 template <typename TResources, typename TOperationID, typename TOffer>
1476 inline typename TOffer::Operation CREATE(
1477  const TResources& volumes,
1478  const Option<TOperationID>& operationId = None())
1479 {
1480  typename TOffer::Operation operation;
1481  operation.set_type(TOffer::Operation::CREATE);
1482  operation.mutable_create()->mutable_volumes()->CopyFrom(volumes);
1483 
1484  if (operationId.isSome()) {
1485  *operation.mutable_id() = operationId.get();
1486  }
1487 
1488  return operation;
1489 }
1490 
1491 
1492 template <typename TResources, typename TOperationID, typename TOffer>
1493 inline typename TOffer::Operation DESTROY(
1494  const TResources& volumes,
1495  const Option<TOperationID>& operationId = None())
1496 {
1497  typename TOffer::Operation operation;
1498  operation.set_type(TOffer::Operation::DESTROY);
1499  operation.mutable_destroy()->mutable_volumes()->CopyFrom(volumes);
1500 
1501  if (operationId.isSome()) {
1502  *operation.mutable_id() = operationId.get();
1503  }
1504 
1505  return operation;
1506 }
1507 
1508 
1509 template <typename TResource, typename TOperationID, typename TOffer>
1511  const TResource& volume,
1512  const TResource& addition,
1513  const Option<TOperationID>& operationId = None())
1514 {
1515  typename TOffer::Operation operation;
1516  operation.set_type(TOffer::Operation::GROW_VOLUME);
1517  operation.mutable_grow_volume()->mutable_volume()->CopyFrom(volume);
1518  operation.mutable_grow_volume()->mutable_addition()->CopyFrom(addition);
1519 
1520  if (operationId.isSome()) {
1521  *operation.mutable_id() = operationId.get();
1522  }
1523 
1524  return operation;
1525 }
1526 
1527 
1528 template <
1529  typename TResource,
1530  typename TValueScalar,
1531  typename TOperationID,
1532  typename TOffer>
1534  const TResource& volume,
1535  const TValueScalar& subtract,
1536  const Option<TOperationID>& operationId = None())
1537 {
1538  typename TOffer::Operation operation;
1539  operation.set_type(TOffer::Operation::SHRINK_VOLUME);
1540  operation.mutable_shrink_volume()->mutable_volume()->CopyFrom(volume);
1541  operation.mutable_shrink_volume()->mutable_subtract()->CopyFrom(subtract);
1542 
1543  if (operationId.isSome()) {
1544  *operation.mutable_id() = operationId.get();
1545  }
1546 
1547  return operation;
1548 }
1549 
1550 
1551 template <typename TOffer, typename TTaskInfo>
1552 inline typename TOffer::Operation LAUNCH(const std::vector<TTaskInfo>& tasks)
1553 {
1554  typename TOffer::Operation operation;
1555  operation.set_type(TOffer::Operation::LAUNCH);
1556 
1557  foreach (const TTaskInfo& task, tasks) {
1558  operation.mutable_launch()->add_task_infos()->CopyFrom(task);
1559  }
1560 
1561  return operation;
1562 }
1563 
1564 
1565 template <typename TExecutorInfo, typename TTaskGroupInfo, typename TOffer>
1567  const TExecutorInfo& executorInfo,
1568  const TTaskGroupInfo& taskGroup)
1569 {
1570  typename TOffer::Operation operation;
1571  operation.set_type(TOffer::Operation::LAUNCH_GROUP);
1572  operation.mutable_launch_group()->mutable_executor()->CopyFrom(executorInfo);
1573  operation.mutable_launch_group()->mutable_task_group()->CopyFrom(taskGroup);
1574  return operation;
1575 }
1576 
1577 
1578 template <
1579  typename TResource,
1580  typename TTargetType,
1581  typename TOperationID,
1582  typename TOffer>
1584  const TResource& source,
1585  const TTargetType& targetType,
1586  const Option<std::string>& targetProfile = None(),
1587  const Option<TOperationID>& operationId = None())
1588 {
1589  typename TOffer::Operation operation;
1590  operation.set_type(TOffer::Operation::CREATE_DISK);
1591  operation.mutable_create_disk()->mutable_source()->CopyFrom(source);
1592  operation.mutable_create_disk()->set_target_type(targetType);
1593 
1594  if (targetProfile.isSome()) {
1595  operation.mutable_create_disk()->set_target_profile(targetProfile.get());
1596  }
1597 
1598  if (operationId.isSome()) {
1599  operation.mutable_id()->CopyFrom(operationId.get());
1600  }
1601 
1602  return operation;
1603 }
1604 
1605 
1606 template <typename TResource, typename TOperationID, typename TOffer>
1608  const TResource& source, const Option<TOperationID>& operationId = None())
1609 {
1610  typename TOffer::Operation operation;
1611  operation.set_type(TOffer::Operation::DESTROY_DISK);
1612  operation.mutable_destroy_disk()->mutable_source()->CopyFrom(source);
1613 
1614  if (operationId.isSome()) {
1615  operation.mutable_id()->CopyFrom(operationId.get());
1616  }
1617 
1618  return operation;
1619 }
1620 
1621 
1622 template <typename TParameters, typename TParameter>
1623 inline TParameters parameterize(const ACLs& acls)
1624 {
1625  TParameters parameters;
1626  TParameter* parameter = parameters.add_parameter();
1627  parameter->set_key("acls");
1628  parameter->set_value(std::string(jsonify(JSON::Protobuf(acls))));
1629 
1630  return parameters;
1631 }
1632 } // namespace common {
1633 
1634 
1635 // TODO(jmlvanre): Remove `inline` once we have adjusted all tests to
1636 // distinguish between `internal` and `v1`.
1637 inline namespace internal {
1638 template <typename... Args>
1639 inline ExecutorInfo createExecutorInfo(Args&&... args)
1640 {
1642  ExecutorInfo,
1643  ExecutorID,
1644  Resources,
1645  CommandInfo,
1646  FrameworkID>(std::forward<Args>(args)...);
1647 }
1648 
1649 
1650 // We specify the argument to allow brace initialized construction.
1651 inline CommandInfo createCommandInfo(
1652  const Option<std::string>& value = None(),
1653  const std::vector<std::string>& arguments = {})
1654 {
1655  return common::createCommandInfo<CommandInfo>(value, arguments);
1656 }
1657 
1658 
1659 // Almost a direct snippet of code at the bottom of `Slave::launchExecutor`.
1660 inline mesos::slave::ContainerConfig createContainerConfig(
1661  const Option<TaskInfo>& taskInfo,
1662  const ExecutorInfo& executorInfo,
1663  const std::string& sandboxDirectory,
1664  const Option<std::string>& user = None())
1665 {
1666  mesos::slave::ContainerConfig containerConfig;
1667  containerConfig.mutable_executor_info()->CopyFrom(executorInfo);
1668  containerConfig.mutable_command_info()->CopyFrom(executorInfo.command());
1669  containerConfig.mutable_resources()->CopyFrom(executorInfo.resources());
1670  containerConfig.set_directory(sandboxDirectory);
1671 
1672  if (user.isSome()) {
1673  containerConfig.set_user(user.get());
1674  }
1675 
1676  if (taskInfo.isSome()) {
1677  containerConfig.mutable_task_info()->CopyFrom(taskInfo.get());
1678 
1679  if (taskInfo->has_container()) {
1680  containerConfig.mutable_container_info()->CopyFrom(taskInfo->container());
1681  }
1682  } else {
1683  if (executorInfo.has_container()) {
1684  containerConfig.mutable_container_info()
1685  ->CopyFrom(executorInfo.container());
1686  }
1687  }
1688 
1689  return containerConfig;
1690 }
1691 
1692 
1693 // Almost a direct snippet of code in `Slave::Http::_launchNestedContainer`.
1694 inline mesos::slave::ContainerConfig createContainerConfig(
1695  const CommandInfo& commandInfo,
1696  const Option<ContainerInfo>& containerInfo = None(),
1697  const Option<mesos::slave::ContainerClass>& containerClass = None(),
1698  const Option<std::string>& user = None())
1699 {
1700  mesos::slave::ContainerConfig containerConfig;
1701  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1702 
1703  if (user.isSome()) {
1704  containerConfig.set_user(user.get());
1705  }
1706 
1707  if (containerInfo.isSome()) {
1708  containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
1709  }
1710 
1711  if (containerClass.isSome()) {
1712  containerConfig.set_container_class(containerClass.get());
1713  }
1714 
1715  return containerConfig;
1716 }
1717 
1718 
1719 // Helper for creating standalone container configs.
1720 inline mesos::slave::ContainerConfig createContainerConfig(
1721  const CommandInfo& commandInfo,
1722  const std::string& resources,
1723  const std::string& sandboxDirectory,
1724  const Option<ContainerInfo>& containerInfo = None(),
1725  const Option<std::string>& user = None())
1726 {
1727  mesos::slave::ContainerConfig containerConfig;
1728  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1729  containerConfig.mutable_resources()->CopyFrom(
1730  Resources::parse(resources).get());
1731 
1732  containerConfig.set_directory(sandboxDirectory);
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  return containerConfig;
1743 }
1744 
1745 
1746 template <typename... Args>
1747 inline Image createDockerImage(Args&&... args)
1748 {
1749  return common::createDockerImage<Image>(std::forward<Args>(args)...);
1750 }
1751 
1752 
1753 template <typename... Args>
1754 inline Volume createVolumeSandboxPath(Args&&... args)
1755 {
1756  return common::createVolumeSandboxPath<Volume>(std::forward<Args>(args)...);
1757 }
1758 
1759 
1760 template <typename... Args>
1761 inline Volume createVolumeHostPath(Args&&... args)
1762 {
1763  return common::createVolumeHostPath<Volume, MountPropagation>(
1764  std::forward<Args>(args)...);
1765 }
1766 
1767 
1768 template <typename... Args>
1769 inline Volume createVolumeFromDockerImage(Args&&... args)
1770 {
1771  return common::createVolumeFromDockerImage<Volume, Image>(
1772  std::forward<Args>(args)...);
1773 }
1774 
1775 
1776 template <typename... Args>
1777 inline Volume createVolumeCsi(Args&&... args)
1778 {
1779  return common::createVolumeCsi<Volume>(
1780  std::forward<Args>(args)...);
1781 }
1782 
1783 
1784 template <typename... Args>
1785 inline NetworkInfo createNetworkInfo(Args&&... args)
1786 {
1787  return common::createNetworkInfo<NetworkInfo>(std::forward<Args>(args)...);
1788 }
1789 
1790 
1791 // We specify the argument to allow brace initialized construction.
1792 inline ContainerInfo createContainerInfo(
1793  const Option<std::string>& imageName = None(),
1794  const std::vector<Volume>& volumes = {})
1795 {
1796  return common::createContainerInfo<ContainerInfo, Volume, Image>(
1797  imageName,
1798  volumes);
1799 }
1800 
1801 
1802 template <typename... Args>
1803 inline TaskInfo createTask(Args&&... args)
1804 {
1805  return common::createTask<
1806  TaskInfo,
1807  ExecutorID,
1808  SlaveID,
1809  Resources,
1810  ExecutorInfo,
1811  CommandInfo,
1812  Offer,
1813  Value::Scalar>(std::forward<Args>(args)...);
1814 }
1815 
1816 
1817 // We specify the argument to allow brace initialized construction.
1818 inline TaskGroupInfo createTaskGroupInfo(const std::vector<TaskInfo>& tasks)
1819 {
1820  return common::createTaskGroupInfo<TaskGroupInfo, TaskInfo>(tasks);
1821 }
1822 
1823 
1824 inline Resource::ReservationInfo createStaticReservationInfo(
1825  const std::string& role)
1826 {
1827  return common::createStaticReservationInfo<Resource>(role);
1828 }
1829 
1830 
1831 inline Resource::ReservationInfo createDynamicReservationInfo(
1832  const std::string& role,
1833  const Option<std::string>& principal = None(),
1834  const Option<Labels>& labels = None())
1835 {
1836  return common::createDynamicReservationInfo<Resource, Labels>(
1837  role, principal, labels);
1838 }
1839 
1840 
1841 template <typename... Args>
1842 inline Resource createReservedResource(Args&&... args)
1843 {
1844  return common::createReservedResource<Resource, Resources>(
1845  std::forward<Args>(args)...);
1846 }
1847 
1848 
1849 template <typename... Args>
1850 inline Resource::DiskInfo createDiskInfo(Args&&... args)
1851 {
1852  return common::createDiskInfo<Resource, Volume>(std::forward<Args>(args)...);
1853 }
1854 
1855 
1856 template <typename... Args>
1857 inline Resource::DiskInfo::Source createDiskSourcePath(Args&&... args)
1858 {
1859  return common::createDiskSourcePath<Resource>(std::forward<Args>(args)...);
1860 }
1861 
1862 
1863 template <typename... Args>
1864 inline Resource::DiskInfo::Source createDiskSourceMount(Args&&... args)
1865 {
1866  return common::createDiskSourceMount<Resource>(std::forward<Args>(args)...);
1867 }
1868 
1869 
1870 template <typename... Args>
1871 inline Resource::DiskInfo::Source createDiskSourceBlock(Args&&... args)
1872 {
1873  return common::createDiskSourceBlock<Resource>(std::forward<Args>(args)...);
1874 }
1875 
1876 
1877 template <typename... Args>
1878 inline Resource::DiskInfo::Source createDiskSourceRaw(Args&&... args)
1879 {
1880  return common::createDiskSourceRaw<Resource>(std::forward<Args>(args)...);
1881 }
1882 
1883 
1884 template <typename... Args>
1885 inline Resource createDiskResource(Args&&... args)
1886 {
1887  return common::createDiskResource<Resource, Resources, Volume>(
1888  std::forward<Args>(args)...);
1889 }
1890 
1891 
1892 template <typename... Args>
1893 inline Resource createPersistentVolume(Args&&... args)
1894 {
1895  return common::createPersistentVolume<Resource, Resources, Volume>(
1896  std::forward<Args>(args)...);
1897 }
1898 
1899 
1900 template <typename... Args>
1902 {
1903  return common::createBasicAuthHeaders<Credential>(
1904  std::forward<Args>(args)...);
1905 }
1906 
1907 
1908 template <typename... Args>
1909 inline google::protobuf::RepeatedPtrField<WeightInfo> createWeightInfos(
1910  Args&&... args)
1911 {
1912  return common::createWeightInfos<WeightInfo>(std::forward<Args>(args)...);
1913 }
1914 
1915 
1916 template <typename... Args>
1918 {
1919  return common::convertToHashmap<WeightInfo>(std::forward<Args>(args)...);
1920 }
1921 
1922 
1923 template <typename... Args>
1924 inline DomainInfo createDomainInfo(Args&&... args)
1925 {
1926  return common::createDomainInfo<DomainInfo>(std::forward<Args>(args)...);
1927 }
1928 
1929 
1930 template <typename... Args>
1931 inline Offer::Operation RESERVE(Args&&... args)
1932 {
1933  return common::RESERVE<Resources, OperationID, Offer>(
1934  std::forward<Args>(args)...);
1935 }
1936 
1937 
1938 template <typename... Args>
1939 inline Offer::Operation UNRESERVE(Args&&... args)
1940 {
1941  return common::UNRESERVE<Resources, OperationID, Offer>(
1942  std::forward<Args>(args)...);
1943 }
1944 
1945 
1946 template <typename... Args>
1947 inline Offer::Operation CREATE(Args&&... args)
1948 {
1949  return common::CREATE<Resources, OperationID, Offer>(
1950  std::forward<Args>(args)...);
1951 }
1952 
1953 
1954 template <typename... Args>
1955 inline Offer::Operation DESTROY(Args&&... args)
1956 {
1957  return common::DESTROY<Resources, OperationID, Offer>(
1958  std::forward<Args>(args)...);
1959 }
1960 
1961 
1962 template <typename... Args>
1963 inline Offer::Operation GROW_VOLUME(Args&&... args)
1964 {
1965  return common::GROW_VOLUME<Resource, OperationID, Offer>(
1966  std::forward<Args>(args)...);
1967 }
1968 
1969 
1970 template <typename... Args>
1971 inline Offer::Operation SHRINK_VOLUME(Args&&... args)
1972 {
1973  return common::SHRINK_VOLUME<Resource, Value::Scalar, OperationID, Offer>(
1974  std::forward<Args>(args)...);
1975 }
1976 
1977 
1978 // We specify the argument to allow brace initialized construction.
1979 inline Offer::Operation LAUNCH(const std::vector<TaskInfo>& tasks)
1980 {
1981  return common::LAUNCH<Offer, TaskInfo>(tasks);
1982 }
1983 
1984 
1985 template <typename... Args>
1986 inline Offer::Operation LAUNCH_GROUP(Args&&... args)
1987 {
1988  return common::LAUNCH_GROUP<ExecutorInfo, TaskGroupInfo, Offer>(
1989  std::forward<Args>(args)...);
1990 }
1991 
1992 
1993 template <typename... Args>
1994 inline Offer::Operation CREATE_DISK(Args&&... args)
1995 {
1996  return common::
1997  CREATE_DISK<Resource, Resource::DiskInfo::Source::Type, OperationID, Offer>(
1998  std::forward<Args>(args)...);
1999 }
2000 
2001 
2002 template <typename... Args>
2003 inline Offer::Operation DESTROY_DISK(Args&&... args)
2004 {
2005  return common::DESTROY_DISK<Resource, OperationID, Offer>(
2006  std::forward<Args>(args)...);
2007 }
2008 
2009 
2010 template <typename... Args>
2011 inline Parameters parameterize(Args&&... args)
2012 {
2013  return common::parameterize<Parameters, Parameter>(
2014  std::forward<Args>(args)...);
2015 }
2016 } // namespace internal {
2017 
2018 
2019 namespace v1 {
2020 template <typename... Args>
2021 inline mesos::v1::ExecutorInfo createExecutorInfo(Args&&... args)
2022 {
2024  mesos::v1::ExecutorInfo,
2025  mesos::v1::ExecutorID,
2027  mesos::v1::CommandInfo,
2028  mesos::v1::FrameworkID>(std::forward<Args>(args)...);
2029 }
2030 
2031 
2032 // We specify the argument to allow brace initialized construction.
2033 inline mesos::v1::CommandInfo createCommandInfo(
2034  const Option<std::string>& value = None(),
2035  const std::vector<std::string>& arguments = {})
2036 {
2037  return common::createCommandInfo<mesos::v1::CommandInfo>(value, arguments);
2038 }
2039 
2040 
2041 template <typename... Args>
2042 inline mesos::v1::Image createDockerImage(Args&&... args)
2043 {
2044  return common::createDockerImage<mesos::v1::Image>(
2045  std::forward<Args>(args)...);
2046 }
2047 
2048 
2049 template <typename... Args>
2050 inline mesos::v1::Volume createVolumeSandboxPath(Args&&... args)
2051 {
2052  return common::createVolumeSandboxPath<mesos::v1::Volume>(
2053  std::forward<Args>(args)...);
2054 }
2055 
2056 
2057 template <typename... Args>
2058 inline mesos::v1::Volume createVolumeHostPath(Args&&... args)
2059 {
2061  mesos::v1::Volume,
2062  mesos::v1::MountPropagation>(std::forward<Args>(args)...);
2063 }
2064 
2065 
2066 template <typename... Args>
2067 inline mesos::v1::Volume createVolumeFromDockerImage(Args&&... args)
2068 {
2070  mesos::v1::Volume, mesos::v1::Image>(std::forward<Args>(args)...);
2071 }
2072 
2073 
2074 template <typename... Args>
2075 inline mesos::v1::Volume createVolumeCsi(Args&&... args)
2076 {
2077  return common::createVolumeCsi<mesos::v1::Volume>(
2078  std::forward<Args>(args)...);
2079 }
2080 
2081 
2082 template <typename... Args>
2083 inline mesos::v1::NetworkInfo createNetworkInfo(Args&&... args)
2084 {
2085  return common::createNetworkInfo<mesos::v1::NetworkInfo>(
2086  std::forward<Args>(args)...);
2087 }
2088 
2089 
2090 // We specify the argument to allow brace initialized construction.
2091 inline mesos::v1::ContainerInfo createContainerInfo(
2092  const Option<std::string>& imageName = None(),
2093  const std::vector<mesos::v1::Volume>& volumes = {})
2094 {
2096  mesos::v1::ContainerInfo, mesos::v1::Volume, mesos::v1::Image>(
2097  imageName, volumes);
2098 }
2099 
2100 
2101 template <typename... Args>
2102 inline mesos::v1::TaskInfo createTask(Args&&... args)
2103 {
2104  return common::createTask<
2105  mesos::v1::TaskInfo,
2106  mesos::v1::ExecutorID,
2107  mesos::v1::AgentID,
2109  mesos::v1::ExecutorInfo,
2110  mesos::v1::CommandInfo,
2111  mesos::v1::Offer,
2112  mesos::v1::Value::Scalar>(std::forward<Args>(args)...);
2113 }
2114 
2115 
2116 // We specify the argument to allow brace initialized construction.
2117 inline mesos::v1::TaskGroupInfo createTaskGroupInfo(
2118  const std::vector<mesos::v1::TaskInfo>& tasks)
2119 {
2121  mesos::v1::TaskGroupInfo,
2122  mesos::v1::TaskInfo>(tasks);
2123 }
2124 
2125 
2126 inline mesos::v1::Resource::ReservationInfo createStaticReservationInfo(
2127  const std::string& role)
2128 {
2129  return common::createStaticReservationInfo<mesos::v1::Resource>(role);
2130 }
2131 
2132 
2133 inline mesos::v1::Resource::ReservationInfo createDynamicReservationInfo(
2134  const std::string& role,
2135  const Option<std::string>& principal = None(),
2136  const Option<mesos::v1::Labels>& labels = None())
2137 {
2139  mesos::v1::Resource, mesos::v1::Labels>(role, principal, labels);
2140 }
2141 
2142 
2143 template <typename... Args>
2144 inline mesos::v1::Resource createReservedResource(Args&&... args)
2145 {
2147  mesos::v1::Resource, mesos::v1::Resources>(std::forward<Args>(args)...);
2148 }
2149 
2150 
2151 template <typename... Args>
2152 inline mesos::v1::Resource::DiskInfo createDiskInfo(Args&&... args)
2153 {
2154  return common::createDiskInfo<mesos::v1::Resource, mesos::v1::Volume>(
2155  std::forward<Args>(args)...);
2156 }
2157 
2158 
2159 template <typename... Args>
2160 inline mesos::v1::Resource::DiskInfo::Source createDiskSourcePath(
2161  Args&&... args)
2162 {
2163  return common::createDiskSourcePath<mesos::v1::Resource>(
2164  std::forward<Args>(args)...);
2165 }
2166 
2167 
2168 template <typename... Args>
2169 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceMount(
2170  Args&&... args)
2171 {
2172  return common::createDiskSourceMount<mesos::v1::Resource>(
2173  std::forward<Args>(args)...);
2174 }
2175 
2176 
2177 template <typename... Args>
2178 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(
2179  Args&&... args)
2180 {
2181  return common::createDiskSourceBlock<mesos::v1::Resource>(
2182  std::forward<Args>(args)...);
2183 }
2184 
2185 
2186 template <typename... Args>
2187 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceRaw(
2188  Args&&... args)
2189 {
2190  return common::createDiskSourceRaw<mesos::v1::Resource>(
2191  std::forward<Args>(args)...);
2192 }
2193 
2194 
2195 template <typename... Args>
2196 inline mesos::v1::Resource createDiskResource(Args&&... args)
2197 {
2199  mesos::v1::Resource,
2201  mesos::v1::Volume>(std::forward<Args>(args)...);
2202 }
2203 
2204 
2205 template <typename... Args>
2206 inline mesos::v1::Resource createPersistentVolume(Args&&... args)
2207 {
2209  mesos::v1::Resource,
2211  mesos::v1::Volume>(std::forward<Args>(args)...);
2212 }
2213 
2214 
2215 template <typename... Args>
2217 {
2218  return common::createBasicAuthHeaders<mesos::v1::Credential>(
2219  std::forward<Args>(args)...);
2220 }
2221 
2222 
2223 template <typename... Args>
2224 inline google::protobuf::RepeatedPtrField<
2225  mesos::v1::WeightInfo> createWeightInfos(Args&&... args)
2226 {
2227  return common::createWeightInfos<mesos::v1::WeightInfo>(
2228  std::forward<Args>(args)...);
2229 }
2230 
2231 
2232 template <typename... Args>
2234 {
2235  return common::convertToHashmap<mesos::v1::WeightInfo>(
2236  std::forward<Args>(args)...);
2237 }
2238 
2239 
2240 template <typename... Args>
2241 inline mesos::v1::Offer::Operation RESERVE(Args&&... args)
2242 {
2243  return common::RESERVE<
2245  mesos::v1::OperationID,
2246  mesos::v1::Offer>(std::forward<Args>(args)...);
2247 }
2248 
2249 
2250 template <typename... Args>
2252 {
2253  return common::UNRESERVE<
2255  mesos::v1::OperationID,
2256  mesos::v1::Offer>(std::forward<Args>(args)...);
2257 }
2258 
2259 
2260 template <typename... Args>
2261 inline mesos::v1::Offer::Operation CREATE(Args&&... args)
2262 {
2263  return common::CREATE<
2265  mesos::v1::OperationID,
2266  mesos::v1::Offer>(std::forward<Args>(args)...);
2267 }
2268 
2269 
2270 template <typename... Args>
2271 inline mesos::v1::Offer::Operation DESTROY(Args&&... args)
2272 {
2273  return common::DESTROY<
2275  mesos::v1::OperationID,
2276  mesos::v1::Offer>(std::forward<Args>(args)...);
2277 }
2278 
2279 
2280 template <typename... Args>
2282 {
2283  return common::GROW_VOLUME<
2284  mesos::v1::Resource,
2285  mesos::v1::OperationID,
2286  mesos::v1::Offer>(std::forward<Args>(args)...);
2287 }
2288 
2289 
2290 template <typename... Args>
2292 {
2293  return common::SHRINK_VOLUME<
2294  mesos::v1::Resource,
2295  mesos::v1::Value::Scalar,
2296  mesos::v1::OperationID,
2297  mesos::v1::Offer>(std::forward<Args>(args)...);
2298 }
2299 
2300 
2301 // We specify the argument to allow brace initialized construction.
2303  const std::vector<mesos::v1::TaskInfo>& tasks)
2304 {
2305  return common::LAUNCH<mesos::v1::Offer, mesos::v1::TaskInfo>(tasks);
2306 }
2307 
2308 
2309 template <typename... Args>
2311 {
2312  return common::LAUNCH_GROUP<
2313  mesos::v1::ExecutorInfo,
2314  mesos::v1::TaskGroupInfo,
2315  mesos::v1::Offer>(std::forward<Args>(args)...);
2316 }
2317 
2318 
2319 template <typename... Args>
2321 {
2322  return common::CREATE_DISK<
2323  mesos::v1::Resource,
2325  mesos::v1::OperationID,
2326  mesos::v1::Offer>(std::forward<Args>(args)...);
2327 }
2328 
2329 
2330 template <typename... Args>
2332 {
2333  return common::DESTROY_DISK<
2334  mesos::v1::Resource,
2335  mesos::v1::OperationID,
2336  mesos::v1::Offer>(std::forward<Args>(args)...);
2337 }
2338 
2339 
2340 template <typename... Args>
2341 inline mesos::v1::Parameters parameterize(Args&&... args)
2342 {
2343  return common::parameterize<mesos::v1::Parameters, mesos::v1::Parameter>(
2344  std::forward<Args>(args)...);
2345 }
2346 
2347 
2349  const mesos::v1::FrameworkID& frameworkId,
2350  const mesos::v1::Offer& offer,
2351  const std::vector<mesos::v1::Offer::Operation>& operations,
2353 {
2355  call.set_type(mesos::v1::scheduler::Call::ACCEPT);
2356  call.mutable_framework_id()->CopyFrom(frameworkId);
2357 
2358  mesos::v1::scheduler::Call::Accept* accept = call.mutable_accept();
2359  accept->add_offer_ids()->CopyFrom(offer.id());
2360 
2361  foreach (const mesos::v1::Offer::Operation& operation, operations) {
2362  accept->add_operations()->CopyFrom(operation);
2363  }
2364 
2365  if (filters.isSome()) {
2366  accept->mutable_filters()->CopyFrom(filters.get());
2367  }
2368 
2369  return call;
2370 }
2371 
2372 
2374  const mesos::v1::FrameworkID& frameworkId,
2375  const mesos::v1::AgentID& agentId,
2376  const mesos::v1::scheduler::Event::Update& update)
2377 {
2379  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE);
2380  call.mutable_framework_id()->CopyFrom(frameworkId);
2381 
2382  mesos::v1::scheduler::Call::Acknowledge* acknowledge =
2383  call.mutable_acknowledge();
2384 
2385  acknowledge->mutable_task_id()->CopyFrom(
2386  update.status().task_id());
2387 
2388  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2389  acknowledge->set_uuid(update.status().uuid());
2390 
2391  return call;
2392 }
2393 
2394 
2396  const mesos::v1::FrameworkID& frameworkId,
2397  const mesos::v1::AgentID& agentId,
2398  const Option<mesos::v1::ResourceProviderID>& resourceProviderId,
2399  const mesos::v1::scheduler::Event::UpdateOperationStatus& update)
2400 {
2402  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE_OPERATION_STATUS);
2403  call.mutable_framework_id()->CopyFrom(frameworkId);
2404 
2405  mesos::v1::scheduler::Call::AcknowledgeOperationStatus* acknowledge =
2406  call.mutable_acknowledge_operation_status();
2407 
2408  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2409  if (resourceProviderId.isSome()) {
2410  acknowledge->mutable_resource_provider_id()->CopyFrom(
2411  resourceProviderId.get());
2412  }
2413  acknowledge->set_uuid(update.status().uuid().value());
2414  acknowledge->mutable_operation_id()->CopyFrom(update.status().operation_id());
2415 
2416  return call;
2417 }
2418 
2419 
2421  const mesos::v1::FrameworkID& frameworkId,
2422  const mesos::v1::TaskID& taskId,
2423  const Option<mesos::v1::AgentID>& agentId = None(),
2424  const Option<mesos::v1::KillPolicy>& killPolicy = None())
2425 {
2427  call.set_type(mesos::v1::scheduler::Call::KILL);
2428  call.mutable_framework_id()->CopyFrom(frameworkId);
2429 
2430  mesos::v1::scheduler::Call::Kill* kill = call.mutable_kill();
2431  kill->mutable_task_id()->CopyFrom(taskId);
2432 
2433  if (agentId.isSome()) {
2434  kill->mutable_agent_id()->CopyFrom(agentId.get());
2435  }
2436 
2437  if (killPolicy.isSome()) {
2438  kill->mutable_kill_policy()->CopyFrom(killPolicy.get());
2439  }
2440 
2441  return call;
2442 }
2443 
2444 
2446  const mesos::v1::FrameworkID& frameworkId,
2447  const std::vector<
2449  operations = {})
2450 {
2452  call.set_type(mesos::v1::scheduler::Call::RECONCILE_OPERATIONS);
2453  call.mutable_framework_id()->CopyFrom(frameworkId);
2454 
2455  mesos::v1::scheduler::Call::ReconcileOperations* reconcile =
2456  call.mutable_reconcile_operations();
2457 
2458  foreach (
2460  operation,
2461  operations) {
2462  reconcile->add_operations()->CopyFrom(operation);
2463  }
2464 
2465  return call;
2466 }
2467 
2468 
2470  const mesos::v1::FrameworkInfo& frameworkInfo,
2471  const Option<mesos::v1::FrameworkID>& frameworkId = None())
2472 {
2474  call.set_type(mesos::v1::scheduler::Call::SUBSCRIBE);
2475 
2476  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2477 
2478  if (frameworkId.isSome()) {
2479  call.mutable_framework_id()->CopyFrom(frameworkId.get());
2480  }
2481 
2482  return call;
2483 }
2484 
2485 } // namespace v1 {
2486 
2487 
2488 inline mesos::Environment createEnvironment(
2490 {
2491  mesos::Environment environment;
2492  foreachpair (const std::string& key, const std::string& value, map) {
2493  mesos::Environment::Variable* variable = environment.add_variables();
2494  variable->set_name(key);
2495  variable->set_value(value);
2496  }
2497  return environment;
2498 }
2499 
2500 
2501 // Macros to get/create (default) ExecutorInfos and FrameworkInfos.
2502 #define DEFAULT_EXECUTOR_INFO createExecutorInfo("default", "exit 1")
2503 
2504 
2505 #define DEFAULT_CREDENTIAL DefaultCredential::create()
2506 #define DEFAULT_CREDENTIAL_2 DefaultCredential2::create()
2507 
2508 
2509 #define DEFAULT_FRAMEWORK_INFO DefaultFrameworkInfo::create()
2510 
2511 
2512 #define DEFAULT_EXECUTOR_ID DEFAULT_EXECUTOR_INFO.executor_id()
2513 
2514 
2515 // Definition of a mock Scheduler to be used in tests with gmock.
2516 class MockScheduler : public Scheduler
2517 {
2518 public:
2519  MockScheduler();
2520  ~MockScheduler() override;
2521 
2522  MOCK_METHOD3(registered, void(SchedulerDriver*,
2523  const FrameworkID&,
2524  const MasterInfo&));
2525  MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
2526  MOCK_METHOD1(disconnected, void(SchedulerDriver*));
2527  MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
2528  const std::vector<Offer>&));
2529  MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
2530  MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
2531  MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
2532  const ExecutorID&,
2533  const SlaveID&,
2534  const std::string&));
2535  MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
2536  MOCK_METHOD4(executorLost, void(SchedulerDriver*,
2537  const ExecutorID&,
2538  const SlaveID&,
2539  int));
2540  MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
2541 };
2542 
2543 // For use with a MockScheduler, for example:
2544 // EXPECT_CALL(sched, resourceOffers(_, _))
2545 // .WillOnce(LaunchTasks(EXECUTOR, TASKS, CPUS, MEM, ROLE));
2546 // Launches up to TASKS no-op tasks, if possible,
2547 // each with CPUS cpus and MEM memory and EXECUTOR executor.
2548 ACTION_P5(LaunchTasks, executor, tasks, cpus, mem, role)
2549 {
2550  SchedulerDriver* driver = arg0;
2551  std::vector<Offer> offers = arg1;
2552  int numTasks = tasks;
2553 
2554  int launched = 0;
2555  for (size_t i = 0; i < offers.size(); i++) {
2556  const Offer& offer = offers[i];
2557 
2558  Resources taskResources = Resources::parse(
2559  "cpus:" + stringify(cpus) + ";mem:" + stringify(mem)).get();
2560 
2561  if (offer.resources_size() > 0 &&
2562  offer.resources(0).has_allocation_info()) {
2563  taskResources.allocate(role);
2564  }
2565 
2566  std::vector<TaskInfo> tasks;
2567  Resources remaining = offer.resources();
2568 
2569  while (remaining.toUnreserved().contains(taskResources) &&
2570  launched < numTasks) {
2571  TaskInfo task;
2572  task.set_name("TestTask");
2573  task.mutable_task_id()->set_value(id::UUID::random().toString());
2574  task.mutable_slave_id()->MergeFrom(offer.slave_id());
2575  task.mutable_executor()->MergeFrom(executor);
2576 
2577  Option<Resources> resources = remaining.find(
2578  role == std::string("*")
2579  ? taskResources
2580  : taskResources.pushReservation(createStaticReservationInfo(role)));
2581 
2582  CHECK_SOME(resources);
2583 
2584  task.mutable_resources()->MergeFrom(resources.get());
2585  remaining -= resources.get();
2586 
2587  tasks.push_back(task);
2588  launched++;
2589  }
2590 
2591  driver->launchTasks(offer.id(), tasks);
2592  }
2593 }
2594 
2595 
2596 // Like LaunchTasks, but decline the entire offer and
2597 // don't launch any tasks.
2598 ACTION(DeclineOffers)
2599 {
2600  SchedulerDriver* driver = arg0;
2601  std::vector<Offer> offers = arg1;
2602 
2603  for (size_t i = 0; i < offers.size(); i++) {
2604  driver->declineOffer(offers[i].id());
2605  }
2606 }
2607 
2608 
2609 // Like DeclineOffers, but takes a custom filters object.
2610 ACTION_P(DeclineOffers, filters)
2611 {
2612  SchedulerDriver* driver = arg0;
2613  std::vector<Offer> offers = arg1;
2614 
2615  for (size_t i = 0; i < offers.size(); i++) {
2616  driver->declineOffer(offers[i].id(), filters);
2617  }
2618 }
2619 
2620 
2621 // For use with a MockScheduler, for example:
2622 // process::Queue<Offer> offers;
2623 // EXPECT_CALL(sched, resourceOffers(_, _))
2624 // .WillRepeatedly(EnqueueOffers(&offers));
2625 // Enqueues all received offers into the provided queue.
2626 ACTION_P(EnqueueOffers, queue)
2627 {
2628  std::vector<Offer> offers = arg1;
2629  foreach (const Offer& offer, offers) {
2630  queue->put(offer);
2631  }
2632 }
2633 
2634 
2635 // Definition of a mock Executor to be used in tests with gmock.
2636 class MockExecutor : public Executor
2637 {
2638 public:
2639  MockExecutor(const ExecutorID& _id);
2640  ~MockExecutor() override;
2641 
2642  MOCK_METHOD4(registered, void(ExecutorDriver*,
2643  const ExecutorInfo&,
2644  const FrameworkInfo&,
2645  const SlaveInfo&));
2646  MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
2647  MOCK_METHOD1(disconnected, void(ExecutorDriver*));
2648  MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
2649  MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
2650  MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
2651  MOCK_METHOD1(shutdown, void(ExecutorDriver*));
2652  MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
2653 
2654  const ExecutorID id;
2655 };
2656 
2657 
2659 {
2660 public:
2662  Scheduler* scheduler,
2665  scheduler,
2667  "",
2668  true,
2670  {
2671  // No-op destructor as _detector lives on the stack.
2672  detector =
2673  std::shared_ptr<mesos::master::detector::MasterDetector>(
2674  _detector, [](mesos::master::detector::MasterDetector*) {});
2675  }
2676 
2678  Scheduler* scheduler,
2680  const FrameworkInfo& framework,
2681  bool implicitAcknowledgements = true)
2683  scheduler,
2684  framework,
2685  "",
2686  implicitAcknowledgements,
2688  {
2689  // No-op destructor as _detector lives on the stack.
2690  detector =
2691  std::shared_ptr<mesos::master::detector::MasterDetector>(
2692  _detector, [](mesos::master::detector::MasterDetector*) {});
2693  }
2694 
2696  Scheduler* scheduler,
2698  const FrameworkInfo& framework,
2699  bool implicitAcknowledgements,
2700  const Credential& credential)
2702  scheduler,
2703  framework,
2704  "",
2705  implicitAcknowledgements,
2706  credential)
2707  {
2708  // No-op destructor as _detector lives on the stack.
2709  detector =
2710  std::shared_ptr<mesos::master::detector::MasterDetector>(
2711  _detector, [](mesos::master::detector::MasterDetector*) {});
2712  }
2713 };
2714 
2715 
2716 namespace scheduler {
2717 
2718 // A generic mock HTTP scheduler to be used in tests with gmock.
2719 template <typename Mesos, typename Event>
2721 {
2722 public:
2723  MOCK_METHOD1_T(connected, void(Mesos*));
2724  MOCK_METHOD1_T(disconnected, void(Mesos*));
2725  MOCK_METHOD1_T(heartbeat, void(Mesos*));
2726  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
2727  MOCK_METHOD2_T(offers, void(Mesos*, const typename Event::Offers&));
2728  MOCK_METHOD2_T(
2729  inverseOffers,
2730  void(Mesos*, const typename Event::InverseOffers&));
2731  MOCK_METHOD2_T(rescind, void(Mesos*, const typename Event::Rescind&));
2732  MOCK_METHOD2_T(
2733  rescindInverseOffers,
2734  void(Mesos*, const typename Event::RescindInverseOffer&));
2735  MOCK_METHOD2_T(update, void(Mesos*, const typename Event::Update&));
2736  MOCK_METHOD2_T(
2737  updateOperationStatus,
2738  void(Mesos*, const typename Event::UpdateOperationStatus&));
2739  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
2740  MOCK_METHOD2_T(failure, void(Mesos*, const typename Event::Failure&));
2741  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
2742 
2743  void events(Mesos* mesos, std::queue<Event> events)
2744  {
2745  while (!events.empty()) {
2746  Event event = std::move(events.front());
2747  events.pop();
2748 
2749  switch (event.type()) {
2750  case Event::SUBSCRIBED:
2751  subscribed(mesos, event.subscribed());
2752  break;
2753  case Event::OFFERS:
2754  offers(mesos, event.offers());
2755  break;
2756  case Event::INVERSE_OFFERS:
2757  inverseOffers(mesos, event.inverse_offers());
2758  break;
2759  case Event::RESCIND:
2760  rescind(mesos, event.rescind());
2761  break;
2762  case Event::RESCIND_INVERSE_OFFER:
2763  rescindInverseOffers(mesos, event.rescind_inverse_offer());
2764  break;
2765  case Event::UPDATE:
2766  update(mesos, event.update());
2767  break;
2768  case Event::UPDATE_OPERATION_STATUS:
2769  updateOperationStatus(mesos, event.update_operation_status());
2770  break;
2771  case Event::MESSAGE:
2772  message(mesos, event.message());
2773  break;
2774  case Event::FAILURE:
2775  failure(mesos, event.failure());
2776  break;
2777  case Event::ERROR:
2778  error(mesos, event.error());
2779  break;
2780  case Event::HEARTBEAT:
2781  heartbeat(mesos);
2782  break;
2783  case Event::UNKNOWN:
2784  LOG(FATAL) << "Received unexpected UNKNOWN event";
2785  break;
2786  }
2787  }
2788  }
2789 };
2790 
2791 
2792 // A generic testing interface for the scheduler library that can be used to
2793 // test the library across various versions.
2794 template <typename Mesos, typename Event>
2795 class TestMesos : public Mesos
2796 {
2797 public:
2799  const std::string& master,
2800  ContentType contentType,
2801  const std::shared_ptr<MockHTTPScheduler<Mesos, Event>>& scheduler,
2802  const Option<std::shared_ptr<mesos::master::detector::MasterDetector>>&
2803  detector = None(),
2804  const mesos::v1::Credential& credential = v1::DEFAULT_CREDENTIAL)
2805  : Mesos(
2806  master,
2807  contentType,
2808  lambda::bind(&MockHTTPScheduler<Mesos, Event>::connected,
2809  scheduler,
2810  this),
2811  lambda::bind(&MockHTTPScheduler<Mesos, Event>::disconnected,
2812  scheduler,
2813  this),
2814  lambda::bind(&MockHTTPScheduler<Mesos, Event>::events,
2815  scheduler,
2816  this,
2817  lambda::_1),
2818  credential,
2819  detector) {}
2820 
2821  ~TestMesos() override
2822  {
2823  // Since the destructor for `TestMesos` is invoked first, the library can
2824  // make more callbacks to the `scheduler` object before the `Mesos` (base
2825  // class) destructor is invoked. To prevent this, we invoke `stop()` here
2826  // to explicitly stop the library.
2827  this->stop();
2828 
2829  bool paused = process::Clock::paused();
2830 
2831  // Need to settle the Clock to ensure that all the pending async callbacks
2832  // with references to `this` and `scheduler` queued on libprocess are
2833  // executed before the object is destructed.
2836 
2837  // Return the Clock to its original state.
2838  if (!paused) {
2840  }
2841  }
2842 };
2843 
2844 } // namespace scheduler {
2845 
2846 
2847 namespace v1 {
2848 namespace scheduler {
2849 
2855 
2856 
2860 
2861 
2862 // This matcher is used to match an offer event that contains a vector of offers
2863 // having any resource that passes the filter.
2864 MATCHER_P(OffersHaveAnyResource, filter, "")
2865 {
2866  foreach (const Offer& offer, arg.offers()) {
2867  foreach (const Resource& resource, offer.resources()) {
2868  if (filter(resource)) {
2869  return true;
2870  }
2871  }
2872  }
2873 
2874  return false;
2875 }
2876 
2877 
2878 // This matcher is used to match the operation ID of an
2879 // `Event.update_operation_status.status` message.
2880 MATCHER_P(OperationStatusUpdateOperationIdEq, operationId, "")
2881 {
2882  return arg.status().has_operation_id() &&
2883  arg.status().operation_id() == operationId;
2884 }
2885 
2886 
2887 // Like LaunchTasks, but decline the entire offer and don't launch any tasks.
2888 ACTION(DeclineOffers)
2889 {
2890  Call call;
2891  call.set_type(Call::DECLINE);
2892 
2893  Call::Decline* decline = call.mutable_decline();
2894 
2895  foreach (const Offer& offer, arg1.offers()) {
2896  decline->add_offer_ids()->CopyFrom(offer.id());
2897 
2898  if (!call.has_framework_id()) {
2899  call.mutable_framework_id()->CopyFrom(offer.framework_id());
2900  }
2901  }
2902 
2903  arg0->send(call);
2904 }
2905 
2906 
2907 ACTION_P(SendSubscribe, frameworkInfo)
2908 {
2909  Call call;
2910  call.set_type(Call::SUBSCRIBE);
2911  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2912 
2913  arg0->send(call);
2914 }
2915 
2916 
2917 ACTION_P2(SendSubscribe, frameworkInfo, frameworkId)
2918 {
2919  Call call;
2920  call.set_type(Call::SUBSCRIBE);
2921  call.mutable_framework_id()->CopyFrom(frameworkId);
2922  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2923  call.mutable_subscribe()->mutable_framework_info()->mutable_id()->CopyFrom(
2924  frameworkId);
2925 
2926  arg0->send(call);
2927 }
2928 
2929 
2930 ACTION_P2(SendAcknowledge, frameworkId, agentId)
2931 {
2932  Call call;
2933  call.set_type(Call::ACKNOWLEDGE);
2934  call.mutable_framework_id()->CopyFrom(frameworkId);
2935 
2936  Call::Acknowledge* acknowledge = call.mutable_acknowledge();
2937  acknowledge->mutable_task_id()->CopyFrom(arg1.status().task_id());
2938  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2939  acknowledge->set_uuid(arg1.status().uuid());
2940 
2941  arg0->send(call);
2942 }
2943 
2944 
2946  SendAcknowledgeOperationStatus, frameworkId, agentId)
2947 {
2948  Call call;
2949  call.set_type(Call::ACKNOWLEDGE_OPERATION_STATUS);
2950  call.mutable_framework_id()->CopyFrom(frameworkId);
2951 
2952  Call::AcknowledgeOperationStatus* acknowledge =
2953  call.mutable_acknowledge_operation_status();
2954 
2955  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2956  acknowledge->set_uuid(arg1.status().uuid().value());
2957  acknowledge->mutable_operation_id()->CopyFrom(arg1.status().operation_id());
2958 
2959  arg0->send(call);
2960 }
2961 
2962 
2964  SendAcknowledgeOperationStatus, frameworkId, agentId, resourceProviderId)
2965 {
2966  Call call;
2967  call.set_type(Call::ACKNOWLEDGE_OPERATION_STATUS);
2968  call.mutable_framework_id()->CopyFrom(frameworkId);
2969 
2970  Call::AcknowledgeOperationStatus* acknowledge =
2971  call.mutable_acknowledge_operation_status();
2972 
2973  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2974  acknowledge->mutable_resource_provider_id()->CopyFrom(resourceProviderId);
2975  acknowledge->set_uuid(arg1.status().uuid().value());
2976  acknowledge->mutable_operation_id()->CopyFrom(arg1.status().operation_id());
2977 
2978  arg0->send(call);
2979 }
2980 
2981 } // namespace scheduler {
2982 
2986 
2987 } // namespace v1 {
2988 
2989 
2990 namespace executor {
2991 
2992 // A generic mock HTTP executor to be used in tests with gmock.
2993 template <typename Mesos, typename Event>
2995 {
2996 public:
2997  MOCK_METHOD1_T(connected, void(Mesos*));
2998  MOCK_METHOD1_T(disconnected, void(Mesos*));
2999  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
3000  MOCK_METHOD2_T(launch, void(Mesos*, const typename Event::Launch&));
3001  MOCK_METHOD2_T(launchGroup, void(Mesos*, const typename Event::LaunchGroup&));
3002  MOCK_METHOD2_T(kill, void(Mesos*, const typename Event::Kill&));
3003  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
3004  MOCK_METHOD1_T(shutdown, void(Mesos*));
3005  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
3006  MOCK_METHOD2_T(acknowledged,
3007  void(Mesos*, const typename Event::Acknowledged&));
3008 
3009  void events(Mesos* mesos, std::queue<Event> events)
3010  {
3011  while (!events.empty()) {
3012  Event event = std::move(events.front());
3013  events.pop();
3014 
3015  switch (event.type()) {
3016  case Event::SUBSCRIBED:
3017  subscribed(mesos, event.subscribed());
3018  break;
3019  case Event::LAUNCH:
3020  launch(mesos, event.launch());
3021  break;
3022  case Event::LAUNCH_GROUP:
3023  launchGroup(mesos, event.launch_group());
3024  break;
3025  case Event::KILL:
3026  kill(mesos, event.kill());
3027  break;
3028  case Event::ACKNOWLEDGED:
3029  acknowledged(mesos, event.acknowledged());
3030  break;
3031  case Event::MESSAGE:
3032  message(mesos, event.message());
3033  break;
3034  case Event::SHUTDOWN:
3035  shutdown(mesos);
3036  break;
3037  case Event::ERROR:
3038  error(mesos, event.error());
3039  break;
3040  case Event::HEARTBEAT:
3041  break;
3042  case Event::UNKNOWN:
3043  LOG(FATAL) << "Received unexpected UNKNOWN event";
3044  break;
3045  }
3046  }
3047  }
3048 };
3049 
3050 
3051 // A generic testing interface for the executor library that can be used to
3052 // test the library across various versions.
3053 template <typename Mesos, typename Event>
3054 class TestMesos : public Mesos
3055 {
3056 public:
3058  ContentType contentType,
3059  const std::shared_ptr<MockHTTPExecutor<Mesos, Event>>& executor,
3060  const std::map<std::string, std::string>& environment)
3061  : Mesos(
3062  contentType,
3063  lambda::bind(&MockHTTPExecutor<Mesos, Event>::connected,
3064  executor,
3065  this),
3066  lambda::bind(&MockHTTPExecutor<Mesos, Event>::disconnected,
3067  executor,
3068  this),
3069  lambda::bind(&MockHTTPExecutor<Mesos, Event>::events,
3070  executor,
3071  this,
3072  lambda::_1),
3073  environment) {}
3074 };
3075 
3076 } // namespace executor {
3077 
3078 
3079 namespace v1 {
3080 namespace executor {
3081 
3082 // Alias existing `mesos::v1::executor` classes so that we can easily
3083 // write `v1::executor::` in tests.
3087 
3088 
3092 
3093 
3094 // TODO(anand): Move these actions to the `v1::executor` namespace.
3095 ACTION_P2(SendSubscribe, frameworkId, executorId)
3096 {
3098  call.mutable_framework_id()->CopyFrom(frameworkId);
3099  call.mutable_executor_id()->CopyFrom(executorId);
3100 
3101  call.set_type(mesos::v1::executor::Call::SUBSCRIBE);
3102 
3103  call.mutable_subscribe();
3104 
3105  arg0->send(call);
3106 }
3107 
3108 
3109 ACTION_P3(SendUpdateFromTask, frameworkId, executorId, state)
3110 {
3111  mesos::v1::TaskStatus status;
3112  status.mutable_task_id()->CopyFrom(arg1.task().task_id());
3113  status.mutable_executor_id()->CopyFrom(executorId);
3114  status.set_state(state);
3115  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
3116  status.set_uuid(id::UUID::random().toBytes());
3117 
3119  call.mutable_framework_id()->CopyFrom(frameworkId);
3120  call.mutable_executor_id()->CopyFrom(executorId);
3121 
3122  call.set_type(mesos::v1::executor::Call::UPDATE);
3123 
3124  call.mutable_update()->mutable_status()->CopyFrom(status);
3125 
3126  arg0->send(call);
3127 }
3128 
3129 
3130 ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
3131 {
3132  mesos::v1::TaskStatus status;
3133  status.mutable_task_id()->CopyFrom(arg1.task_id());
3134  status.mutable_executor_id()->CopyFrom(executorId);
3135  status.set_state(state);
3136  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
3137  status.set_uuid(id::UUID::random().toBytes());
3138 
3140  call.mutable_framework_id()->CopyFrom(frameworkId);
3141  call.mutable_executor_id()->CopyFrom(executorId);
3142 
3143  call.set_type(mesos::v1::executor::Call::UPDATE);
3144 
3145  call.mutable_update()->mutable_status()->CopyFrom(status);
3146 
3147  arg0->send(call);
3148 }
3149 
3150 } // namespace executor {
3151 
3155 
3156 } // namespace v1 {
3157 
3158 
3159 namespace resource_provider {
3160 
3161 template <
3162  typename Event,
3163  typename Call,
3164  typename Driver,
3165  typename ResourceProviderInfo,
3166  typename ResourceProviderID,
3167  typename Resource,
3168  typename Resources,
3169  typename OperationState,
3170  typename Operation>
3172  public process::Process<TestResourceProviderProcess<
3173  Event,
3174  Call,
3175  Driver,
3176  ResourceProviderInfo,
3177  ResourceProviderID,
3178  Resource,
3179  Resources,
3180  OperationState,
3181  Operation>>
3182 {
3183 public:
3185  const ResourceProviderInfo& _info,
3186  const Option<Resources>& _resources = None())
3187  : process::ProcessBase(process::ID::generate("test-resource-provider")),
3188  info(_info),
3189  resources(_resources)
3190  {
3191  auto self = this->self();
3192 
3193  ON_CALL(*this, connected()).WillByDefault(Invoke([self]() {
3194  dispatch(self, &TestResourceProviderProcess::connectedDefault);
3195  }));
3196  EXPECT_CALL(*this, connected()).WillRepeatedly(DoDefault());
3197 
3198  ON_CALL(*this, subscribed(_))
3199  .WillByDefault(
3200  Invoke([self](const typename Event::Subscribed& subscribed) {
3201  dispatch(
3202  self,
3203  &TestResourceProviderProcess::subscribedDefault,
3204  subscribed);
3205  }));
3206  EXPECT_CALL(*this, subscribed(_)).WillRepeatedly(DoDefault());
3207 
3208  ON_CALL(*this, applyOperation(_))
3209  .WillByDefault(
3210  Invoke([self](const typename Event::ApplyOperation& operation) {
3211  dispatch(
3212  self,
3213  &TestResourceProviderProcess::operationDefault,
3214  operation);
3215  }));
3216  EXPECT_CALL(*this, applyOperation(_)).WillRepeatedly(DoDefault());
3217 
3218  ON_CALL(*this, publishResources(_))
3219  .WillByDefault(
3220  Invoke([self](const typename Event::PublishResources& publish) {
3221  dispatch(
3222  self,
3223  &TestResourceProviderProcess::publishDefault,
3224  publish);
3225  }));
3226  EXPECT_CALL(*this, publishResources(_)).WillRepeatedly(DoDefault());
3227 
3228  ON_CALL(*this, teardown()).WillByDefault(Invoke([self]() {
3229  dispatch(self, &TestResourceProviderProcess::teardownDefault);
3230  }));
3231  EXPECT_CALL(*this, teardown()).WillRepeatedly(DoDefault());
3232  }
3233 
3234  MOCK_METHOD0_T(connected, void());
3235  MOCK_METHOD0_T(disconnected, void());
3236  MOCK_METHOD1_T(subscribed, void(const typename Event::Subscribed&));
3237  MOCK_METHOD1_T(applyOperation, void(const typename Event::ApplyOperation&));
3238  MOCK_METHOD1_T(
3239  publishResources,
3240  void(const typename Event::PublishResources&));
3241  MOCK_METHOD1_T(
3242  acknowledgeOperationStatus,
3243  void(const typename Event::AcknowledgeOperationStatus&));
3244  MOCK_METHOD1_T(
3245  reconcileOperations,
3246  void(const typename Event::ReconcileOperations&));
3247  MOCK_METHOD0_T(teardown, void());
3248 
3249  void events(std::queue<Event> events)
3250  {
3251  while (!events.empty()) {
3252  Event event = events.front();
3253 
3254  events.pop();
3255 
3256  switch (event.type()) {
3257  case Event::SUBSCRIBED:
3258  subscribed(event.subscribed());
3259  break;
3260  case Event::APPLY_OPERATION:
3261  applyOperation(event.apply_operation());
3262  break;
3263  case Event::PUBLISH_RESOURCES:
3264  publishResources(event.publish_resources());
3265  break;
3266  case Event::ACKNOWLEDGE_OPERATION_STATUS:
3267  acknowledgeOperationStatus(event.acknowledge_operation_status());
3268  break;
3269  case Event::RECONCILE_OPERATIONS:
3270  reconcileOperations(event.reconcile_operations());
3271  break;
3272  case Event::TEARDOWN:
3273  teardown();
3274  break;
3275  case Event::UNKNOWN:
3276  LOG(FATAL) << "Received unexpected UNKNOWN event";
3277  break;
3278  }
3279  }
3280  }
3281 
3282  process::Future<Nothing> send(const Call& call)
3283  {
3284  if (driver != nullptr) {
3285  return driver->send(call);
3286  } else {
3287  return process::Failure("Cannot send call since driver is torn down");
3288  }
3289  }
3290 
3291  void start(
3293  ContentType contentType)
3294  {
3296 
3297 #ifdef USE_SSL_SOCKET
3299  DEFAULT_JWT_SECRET_KEY);
3300 
3301  // For resource provider authentication the chosen claims don't matter,
3302  // only the signature has to be valid.
3303  // TODO(nfnt): Revisit this once there's authorization of resource provider
3304  // API calls.
3306  claims["foo"] = "bar";
3307 
3308  process::http::authentication::Principal principal(None(), claims);
3309 
3310  process::Future<Secret> secret = secretGenerator.generate(principal);
3311 
3312  token = secretGenerator.generate(principal).then(
3313  [](const Secret& secret) -> Option<std::string> {
3314  return secret.value().data();
3315  });
3316 #endif // USE_SSL_SOCKET
3317 
3318  // TODO(bbannier): Remove the `shared_ptr` once we get C++14.
3319  auto detector_ =
3320  std::make_shared<process::Owned<EndpointDetector>>(std::move(detector));
3321 
3322  token.then(defer(this->self(), [=](const Option<std::string>& token) {
3323  driver.reset(new Driver(
3324  std::move(*detector_),
3325  contentType,
3326  process::defer(this->self(), &TestResourceProviderProcess::connected),
3328  this->self(), &TestResourceProviderProcess::disconnected),
3330  this->self(), &TestResourceProviderProcess::events, lambda::_1),
3331  token));
3332 
3333  driver->start();
3334 
3335  return Nothing();
3336  }));
3337  }
3338 
3339  void stop()
3340  {
3341  driver.reset();
3342  }
3343 
3345  {
3346  Call call;
3347  call.set_type(Call::SUBSCRIBE);
3348  call.mutable_subscribe()->mutable_resource_provider_info()->CopyFrom(info);
3349 
3350  send(call)
3351  .onFailed([](const std::string& failure) {
3352  LOG(INFO) << "Failed to send call: " << failure;
3353  });
3354  }
3355 
3356  void subscribedDefault(const typename Event::Subscribed& subscribed)
3357  {
3358  info.mutable_id()->CopyFrom(subscribed.provider_id());
3359 
3360  providerId.set(subscribed.provider_id());
3361 
3362  if (resources.isSome()) {
3363  Resources injected;
3364 
3365  foreach (Resource resource, resources.get()) {
3366  resource.mutable_provider_id()->CopyFrom(info.id());
3367  injected += resource;
3368  }
3369 
3370  Call call;
3371  call.set_type(Call::UPDATE_STATE);
3372  call.mutable_resource_provider_id()->CopyFrom(info.id());
3373 
3374  typename Call::UpdateState* update = call.mutable_update_state();
3375  update->mutable_resources()->CopyFrom(injected);
3376  update->mutable_resource_version_uuid()->set_value(
3377  id::UUID::random().toBytes());
3378 
3379  send(call)
3380  .onFailed([](const std::string& failure) {
3381  LOG(INFO) << "Failed to send call: " << failure;
3382  });
3383  }
3384  }
3385 
3386  void operationDefault(const typename Event::ApplyOperation& operation)
3387  {
3388  CHECK(info.has_id());
3389 
3390  Call call;
3391  call.set_type(Call::UPDATE_OPERATION_STATUS);
3392  call.mutable_resource_provider_id()->CopyFrom(info.id());
3393 
3394  typename Call::UpdateOperationStatus* update =
3395  call.mutable_update_operation_status();
3396  update->mutable_framework_id()->CopyFrom(operation.framework_id());
3397  update->mutable_operation_uuid()->CopyFrom(operation.operation_uuid());
3398 
3399  update->mutable_status()->set_state(
3400  OperationState::OPERATION_FINISHED);
3401 
3402  switch (operation.info().type()) {
3403  case Operation::LAUNCH:
3405  break;
3406  case Operation::RESERVE:
3407  break;
3408  case Operation::UNRESERVE:
3409  break;
3410  case Operation::CREATE:
3411  break;
3412  case Operation::DESTROY:
3413  break;
3414  // TODO(zhitao): Implement default operation for `GROW_VOLUME` and
3415  // `SHRINK_VOLUME` on mocked resource provider.
3417  break;
3419  break;
3421  update->mutable_status()->add_converted_resources()->CopyFrom(
3422  operation.info().create_disk().source());
3423  update->mutable_status()
3424  ->mutable_converted_resources(0)
3425  ->mutable_disk()
3426  ->mutable_source()
3427  ->set_type(operation.info().create_disk().target_type());
3428  if (operation.info().create_disk().has_target_profile()) {
3429  update->mutable_status()
3430  ->mutable_converted_resources(0)
3431  ->mutable_disk()
3432  ->mutable_source()
3433  ->set_profile(operation.info().create_disk().target_profile());
3434  }
3435  break;
3437  update->mutable_status()->add_converted_resources()->CopyFrom(
3438  operation.info().destroy_disk().source());
3439  update->mutable_status()
3440  ->mutable_converted_resources(0)
3441  ->mutable_disk()
3442  ->mutable_source()
3443  ->set_type(Resource::DiskInfo::Source::RAW);
3444  break;
3445  case Operation::UNKNOWN:
3446  break;
3447  }
3448 
3449  update->mutable_status()->mutable_uuid()->set_value(
3450  id::UUID::random().toString());
3451 
3452  update->mutable_status()->mutable_resource_provider_id()->CopyFrom(
3453  info.id());
3454 
3455  update->mutable_latest_status()->CopyFrom(update->status());
3456 
3457  send(call)
3458  .onFailed([](const std::string& failure) {
3459  LOG(INFO) << "Failed to send call: " << failure;
3460  });
3461  }
3462 
3463  void publishDefault(const typename Event::PublishResources& publish)
3464  {
3465  CHECK(info.has_id());
3466 
3467  Call call;
3468  call.set_type(Call::UPDATE_PUBLISH_RESOURCES_STATUS);
3469  call.mutable_resource_provider_id()->CopyFrom(info.id());
3470 
3471  typename Call::UpdatePublishResourcesStatus* update =
3472  call.mutable_update_publish_resources_status();
3473  update->mutable_uuid()->CopyFrom(publish.uuid());
3474  update->set_status(Call::UpdatePublishResourcesStatus::OK);
3475 
3476  send(call)
3477  .onFailed([](const std::string& failure) {
3478  LOG(INFO) << "Failed to send call: " << failure;
3479  });
3480  }
3481 
3483 
3484  process::Future<ResourceProviderID> id() const { return providerId.future(); }
3485 
3486 private:
3487  ResourceProviderInfo info;
3488 
3489  Option<Resources> resources;
3490  std::unique_ptr<Driver> driver;
3491 
3493 };
3494 
3495 template <
3496  typename Event,
3497  typename Call,
3498  typename Driver,
3499  typename ResourceProviderInfo,
3500  typename ResourceProviderID,
3501  typename Resource,
3502  typename Resources,
3503  typename OperationState,
3504  typename Operation>
3506 {
3507 public:
3509  const ResourceProviderInfo& _info,
3510  const Option<Resources>& _resources = None())
3511  : process(new TestResourceProviderProcessT(_info, _resources))
3512  {
3514  }
3515 
3517  {
3520  }
3521 
3522  void start(
3524  ContentType contentType)
3525  {
3527  *process,
3529  std::move(detector),
3530  contentType);
3531  }
3532 
3533  process::Future<Nothing> send(const Call& call)
3534  {
3535  return process::dispatch(
3537  }
3538 
3539  // Made public for mocking.
3544  mesos::v1::ResourceProviderInfo,
3545  mesos::v1::ResourceProviderID,
3546  mesos::v1::Resource,
3548  mesos::v1::OperationState,
3550 
3551  std::unique_ptr<TestResourceProviderProcessT> process;
3552 };
3553 
3555  const process::UPID& pid)
3556 {
3557  // Start and register a resource provider.
3558  std::string scheme = "http";
3559 
3560 #ifdef USE_SSL_SOCKET
3562  scheme = "https";
3563  }
3564 #endif
3565 
3566  process::http::URL url(
3567  scheme,
3568  pid.address.ip,
3569  pid.address.port,
3570  pid.id + "/api/v1/resource_provider");
3571 
3573 }
3574 
3575 } // namespace resource_provider {
3576 
3577 
3578 namespace v1 {
3579 namespace resource_provider {
3580 
3581 // Alias existing `mesos::v1::resource_provider` classes so that we can easily
3582 // write `v1::resource_provider::` in tests.
3585 
3586 } // namespace resource_provider {
3587 
3593  mesos::v1::ResourceProviderInfo,
3594  mesos::v1::ResourceProviderID,
3595  mesos::v1::Resource,
3597  mesos::v1::OperationState,
3599 
3603  mesos::v1::resource_provider::Driver,
3604  mesos::v1::ResourceProviderInfo,
3605  mesos::v1::ResourceProviderID,
3606  mesos::v1::Resource,
3607  mesos::v1::Resources,
3608  mesos::v1::OperationState,
3610 
3611 } // namespace v1 {
3612 
3613 
3614 // Definition of a MockAuthorizer that can be used in tests with gmock.
3616 {
3617 public:
3618  MockAuthorizer();
3619  ~MockAuthorizer() override;
3620 
3621  MOCK_METHOD1(
3622  authorized, process::Future<bool>(const authorization::Request& request));
3623 
3624  MOCK_METHOD2(
3625  getApprover,
3626  process::Future<std::shared_ptr<const ObjectApprover>>(
3627  const Option<authorization::Subject>& subject,
3628  const authorization::Action& action));
3629 };
3630 
3631 
3632 // Definition of a MockGarbageCollector that can be used in tests with gmock.
3634 {
3635 public:
3636  explicit MockGarbageCollector(const std::string& workDir);
3637  ~MockGarbageCollector() override;
3638 
3639  // The default action is to always return `true`.
3640  MOCK_METHOD1(unschedule, process::Future<bool>(const std::string& path));
3641 };
3642 
3643 
3645 {
3646 public:
3647  MockSecretGenerator() = default;
3648  ~MockSecretGenerator() override = default;
3649 
3650  MOCK_METHOD1(generate, process::Future<Secret>(
3651  const process::http::authentication::Principal& principal));
3652 };
3653 
3654 
3655 ACTION_P(SendStatusUpdateFromTask, state)
3656 {
3657  TaskStatus status;
3658  status.mutable_task_id()->MergeFrom(arg1.task_id());
3659  status.set_state(state);
3660  arg0->sendStatusUpdate(status);
3661 }
3662 
3663 
3664 ACTION_P(SendStatusUpdateFromTaskID, state)
3665 {
3666  TaskStatus status;
3667  status.mutable_task_id()->MergeFrom(arg1);
3668  status.set_state(state);
3669  arg0->sendStatusUpdate(status);
3670 }
3671 
3672 
3673 ACTION_P(SendFrameworkMessage, data)
3674 {
3675  arg0->sendFrameworkMessage(data);
3676 }
3677 
3678 
3679 #define FUTURE_PROTOBUF(message, from, to) \
3680  FutureProtobuf(message, from, to)
3681 
3682 
3683 #define DROP_PROTOBUF(message, from, to) \
3684  FutureProtobuf(message, from, to, true)
3685 
3686 
3687 #define DROP_PROTOBUFS(message, from, to) \
3688  DropProtobufs(message, from, to)
3689 
3690 
3691 #define EXPECT_NO_FUTURE_PROTOBUFS(message, from, to) \
3692  ExpectNoFutureProtobufs(message, from, to)
3693 
3694 
3695 #define FUTURE_HTTP_PROTOBUF(message, path, contentType) \
3696  FutureHttp(message, path, contentType)
3697 
3698 
3699 #define DROP_HTTP_PROTOBUF(message, path, contentType) \
3700  FutureHttp(message, path, contentType, true)
3701 
3702 
3703 #define DROP_HTTP_PROTOBUFS(message, path, contentType) \
3704  DropHttpProtobufs(message, path, contentType)
3705 
3706 
3707 #define EXPECT_NO_FUTURE_HTTP_PROTOBUFS(message, path, contentType) \
3708  ExpectNoFutureHttpProtobufs(message, path, contentType)
3709 
3710 
3711 // These are specialized versions of {FUTURE,DROP}_PROTOBUF that
3712 // capture a scheduler/executor Call protobuf of the given 'type'.
3713 // Note that we name methods as '*ProtobufUnion()' because these could
3714 // be reused for macros that capture any protobufs that are described
3715 // using the standard protocol buffer "union" trick (e.g.,
3716 // FUTURE_EVENT to capture scheduler::Event), see
3717 // https://developers.google.com/protocol-buffers/docs/techniques#union.
3718 
3719 #define FUTURE_CALL(message, unionType, from, to) \
3720  FutureUnionProtobuf(message, unionType, from, to)
3721 
3722 
3723 #define DROP_CALL(message, unionType, from, to) \
3724  FutureUnionProtobuf(message, unionType, from, to, true)
3725 
3726 
3727 #define DROP_CALLS(message, unionType, from, to) \
3728  DropUnionProtobufs(message, unionType, from, to)
3729 
3730 
3731 #define EXPECT_NO_FUTURE_CALLS(message, unionType, from, to) \
3732  ExpectNoFutureUnionProtobufs(message, unionType, from, to)
3733 
3734 
3735 #define FUTURE_CALL_MESSAGE(message, unionType, from, to) \
3736  process::FutureUnionMessage(message, unionType, from, to)
3737 
3738 
3739 #define DROP_CALL_MESSAGE(message, unionType, from, to) \
3740  process::FutureUnionMessage(message, unionType, from, to, true)
3741 
3742 
3743 #define FUTURE_HTTP_CALL(message, unionType, path, contentType) \
3744  FutureUnionHttp(message, unionType, path, contentType)
3745 
3746 
3747 #define DROP_HTTP_CALL(message, unionType, path, contentType) \
3748  FutureUnionHttp(message, unionType, path, contentType, true)
3749 
3750 
3751 #define DROP_HTTP_CALLS(message, unionType, path, contentType) \
3752  DropUnionHttpProtobufs(message, unionType, path, contentType)
3753 
3754 
3755 #define EXPECT_NO_FUTURE_HTTP_CALLS(message, unionType, path, contentType) \
3756  ExpectNoFutureUnionHttpProtobufs(message, unionType, path, contentType)
3757 
3758 
3759 // Forward declaration.
3760 template <typename T>
3761 T _FutureProtobuf(const process::Message& message);
3762 
3763 
3764 template <typename T, typename From, typename To>
3765 process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
3766 {
3767  // Help debugging by adding some "type constraints".
3768  { google::protobuf::Message* m = &t; (void) m; }
3769 
3770  return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
3771  .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
3772 }
3773 
3774 
3775 template <typename Message, typename UnionType, typename From, typename To>
3777  Message message, UnionType unionType, From from, To to, bool drop = false)
3778 {
3779  // Help debugging by adding some "type constraints".
3780  { google::protobuf::Message* m = &message; (void) m; }
3781 
3782  return process::FutureUnionMessage(message, unionType, from, to, drop)
3783  .then(lambda::bind(&_FutureProtobuf<Message>, lambda::_1));
3784 }
3785 
3786 
3787 template <typename Message, typename Path>
3789  Message message,
3790  Path path,
3791  ContentType contentType,
3792  bool drop = false)
3793 {
3794  // Help debugging by adding some "type constraints".
3795  { google::protobuf::Message* m = &message; (void) m; }
3796 
3797  auto deserializer =
3798  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3799 
3800  return process::FutureHttpRequest(message, path, deserializer, drop)
3801  .then([deserializer](const process::http::Request& request) {
3802  return deserializer(request.body).get();
3803  });
3804 }
3805 
3806 
3807 template <typename Message, typename UnionType, typename Path>
3809  Message message,
3810  UnionType unionType,
3811  Path path,
3812  ContentType contentType,
3813  bool drop = false)
3814 {
3815  // Help debugging by adding some "type constraints".
3816  { google::protobuf::Message* m = &message; (void) m; }
3817 
3818  auto deserializer =
3819  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3820 
3822  message, unionType, path, deserializer, drop)
3823  .then([deserializer](const process::http::Request& request) {
3824  return deserializer(request.body).get();
3825  });
3826 }
3827 
3828 
3829 template <typename T>
3831 {
3832  T t;
3833  t.ParseFromString(message.body);
3834  return t;
3835 }
3836 
3837 
3838 template <typename T, typename From, typename To>
3839 void DropProtobufs(T t, From from, To to)
3840 {
3841  // Help debugging by adding some "type constraints".
3842  { google::protobuf::Message* m = &t; (void) m; }
3843 
3844  process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
3845 }
3846 
3847 
3848 template <typename Message, typename UnionType, typename From, typename To>
3849 void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
3850 {
3851  // Help debugging by adding some "type constraints".
3852  { google::protobuf::Message* m = &message; (void) m; }
3853 
3854  process::DropUnionMessages(message, unionType, from, to);
3855 }
3856 
3857 
3858 template <typename Message, typename Path>
3860  Message message,
3861  Path path,
3862  ContentType contentType,
3863  bool drop = false)
3864 {
3865  // Help debugging by adding some "type constraints".
3866  { google::protobuf::Message* m = &message; (void) m; }
3867 
3868  auto deserializer =
3869  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3870 
3871  process::DropHttpRequests(message, path, deserializer);
3872 }
3873 
3874 
3875 template <typename Message, typename UnionType, typename Path>
3877  Message message,
3878  UnionType unionType,
3879  Path path,
3880  ContentType contentType,
3881  bool drop = false)
3882 {
3883  // Help debugging by adding some "type constraints".
3884  { google::protobuf::Message* m = &message; (void) m; }
3885 
3886  auto deserializer =
3887  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3888 
3889  process::DropUnionHttpRequests(message, unionType, path, deserializer);
3890 }
3891 
3892 
3893 template <typename T, typename From, typename To>
3894 void ExpectNoFutureProtobufs(T t, From from, To to)
3895 {
3896  // Help debugging by adding some "type constraints".
3897  { google::protobuf::Message* m = &t; (void) m; }
3898 
3899  process::ExpectNoFutureMessages(testing::Eq(t.GetTypeName()), from, to);
3900 }
3901 
3902 
3903 template <typename Message, typename UnionType, typename From, typename To>
3905  Message message, UnionType unionType, From from, To to)
3906 {
3907  // Help debugging by adding some "type constraints".
3908  { google::protobuf::Message* m = &message; (void) m; }
3909 
3910  process::ExpectNoFutureUnionMessages(message, unionType, from, to);
3911 }
3912 
3913 
3914 template <typename Message, typename Path>
3916  Message message,
3917  Path path,
3918  ContentType contentType,
3919  bool drop = false)
3920 {
3921  // Help debugging by adding some "type constraints".
3922  { google::protobuf::Message* m = &message; (void) m; }
3923 
3924  auto deserializer =
3925  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3926 
3927  process::ExpectNoFutureHttpRequests(message, path, deserializer);
3928 }
3929 
3930 
3931 template <typename Message, typename UnionType, typename Path>
3933  Message message,
3934  UnionType unionType,
3935  Path path,
3936  ContentType contentType,
3937  bool drop = false)
3938 {
3939  // Help debugging by adding some "type constraints".
3940  { google::protobuf::Message* m = &message; (void) m; }
3941 
3942  auto deserializer =
3943  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3944 
3946  message, unionType, path, deserializer);
3947 }
3948 
3949 
3950 // This matcher is used to match a vector of resource offers that
3951 // contains an offer having any resource that passes the filter.
3952 MATCHER_P(OffersHaveAnyResource, filter, "")
3953 {
3954  foreach (const Offer& offer, arg) {
3955  foreach (const Resource& resource, offer.resources()) {
3956  if (filter(resource)) {
3957  return true;
3958  }
3959  }
3960  }
3961 
3962  return false;
3963 }
3964 
3965 
3966 // This matcher is used to match a vector of resource offers that
3967 // contains an offer having the specified resource.
3968 MATCHER_P(OffersHaveResource, resource, "")
3969 {
3970  foreach (const Offer& offer, arg) {
3971  Resources resources = offer.resources();
3972 
3973  // If `resource` is not allocated, we are matching offers against
3974  // resources constructed from scratch, so we strip off allocations.
3975  if (!resource.has_allocation_info()) {
3976  resources.unallocate();
3977  }
3978 
3979  if (resources.contains(resource)) {
3980  return true;
3981  }
3982  }
3983 
3984  return false;
3985 }
3986 
3987 
3988 // This matcher is used to match the task id of a `TaskStatus` message.
3989 MATCHER_P(TaskStatusTaskIdEq, taskId, "")
3990 {
3991  return arg.task_id() == taskId;
3992 }
3993 
3994 
3995 // This matcher is used to match the state of a `TaskStatus` message.
3996 MATCHER_P(TaskStatusStateEq, taskState, "")
3997 {
3998  return arg.state() == taskState;
3999 }
4000 
4001 
4002 // This matcher is used to match the task id of an `Event.update.status`
4003 // message.
4004 MATCHER_P(TaskStatusUpdateTaskIdEq, taskId, "")
4005 {
4006  return arg.status().task_id() == taskId;
4007 }
4008 
4009 
4010 // This matcher is used to match the state of an `Event.update.status`
4011 // message.
4012 MATCHER_P(TaskStatusUpdateStateEq, taskState, "")
4013 {
4014  return arg.status().state() == taskState;
4015 }
4016 
4017 
4018 // This matcher is used to match the task id of
4019 // `authorization::Request.Object.TaskInfo`.
4020 MATCHER_P(AuthorizationRequestHasTaskID, taskId, "")
4021 {
4022  if (!arg.has_object()) {
4023  return false;
4024  }
4025 
4026  if (!arg.object().has_task_info()) {
4027  return false;
4028  }
4029 
4030  return arg.object().task_info().task_id() == taskId;
4031 }
4032 
4033 
4034 // This matcher is used to match the task id of `Option<TaskInfo>`.
4035 MATCHER_P(OptionTaskHasTaskID, taskId, "")
4036 {
4037  return arg.isNone() ? false : arg->task_id() == taskId;
4038 }
4039 
4040 
4041 // This matcher is used to match an `Option<TaskGroupInfo>` which contains a
4042 // task with the specified task id.
4043 MATCHER_P(OptionTaskGroupHasTaskID, taskId, "")
4044 {
4045  if (arg.isNone()) {
4046  return false;
4047  }
4048 
4049  foreach(const TaskInfo& taskInfo, arg->tasks()) {
4050  if (taskInfo.task_id() == taskId) {
4051  return true;
4052  }
4053  }
4054 
4055  return false;
4056 }
4057 
4058 
4060 {
4061 public:
4062  struct Printer
4063  {
4064  std::string operator()(
4065  const ::testing::TestParamInfo<ParamExecutorType>& info) const
4066  {
4067  switch (info.param.type) {
4068  case COMMAND:
4069  return "CommandExecutor";
4070  case DEFAULT:
4071  return "DefaultExecutor";
4072  default:
4073  UNREACHABLE();
4074  }
4075  }
4076  };
4077 
4079  {
4080  return ParamExecutorType(COMMAND);
4081  }
4082 
4084  {
4085  return ParamExecutorType(DEFAULT);
4086  }
4087 
4088  bool isCommandExecutor() const { return type == COMMAND; }
4089  bool isDefaultExecutor() const { return type == DEFAULT; }
4090 
4091 private:
4092  enum Type
4093  {
4094  COMMAND,
4095  DEFAULT
4096  };
4097 
4098  ParamExecutorType(Type _type) : type(_type) {}
4099 
4100  Type type;
4101 };
4102 
4103 
4105 {
4106  enum Type
4107  {
4110  };
4111 
4112  struct Printer
4113  {
4114  std::string operator()(
4115  const ::testing::TestParamInfo<ParamDiskQuota::Type>& info) const;
4116  };
4117 
4118  static std::vector<Type> parameters();
4119 };
4120 
4121 } // namespace tests {
4122 } // namespace internal {
4123 } // namespace mesos {
4124 
4125 #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:2196
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:1459
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:2509
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:2144
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:1924
process::Owned< EndpointDetector > createEndpointDetector(const process::UPID &pid)
Definition: mesos.hpp:3554
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:2021
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:2395
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:2133
mesos::v1::scheduler::Call createCallSubscribe(const mesos::v1::FrameworkInfo &frameworkInfo, const Option< mesos::v1::FrameworkID > &frameworkId=None())
Definition: mesos.hpp:2469
void DropHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3859
Definition: future.hpp:668
mesos::v1::TaskInfo createTask(Args &&...args)
Definition: mesos.hpp:2102
mesos::v1::executor::Event Event
Definition: mesos.hpp:3085
mesos::v1::resource_provider::Event Event
Definition: mesos.hpp:3584
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:934
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:2083
mesos::v1::Volume createVolumeHostPath(Args &&...args)
Definition: mesos.hpp:2058
mesos::v1::Offer::Operation SHRINK_VOLUME(Args &&...args)
Definition: mesos.hpp:2291
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:2320
mesos::v1::scheduler::Call Call
Definition: mesos.hpp:2851
Definition: resources.hpp:83
mesos::v1::Offer::Operation RESERVE(Args &&...args)
Definition: mesos.hpp:2241
Definition: scheduler.hpp:399
std::unique_ptr< TestResourceProviderProcessT > process
Definition: mesos.hpp:3551
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:3484
SlaveOptions & withCsiServer(const process::Owned< slave::CSIServer > &csiServer)
Definition: mesos.hpp:198
bool isCommandExecutor() const
Definition: mesos.hpp:4088
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:2798
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:2091
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:2169
Definition: flags.hpp:39
UPID spawn(ProcessBase *process, bool manage=false)
Spawn a new process.
T _FutureProtobuf(const process::Message &message)
Definition: mesos.hpp:3830
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:2331
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:2033
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:1105
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:1720
void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
Definition: mesos.hpp:3849
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:4104
constexpr const char * arg0
Definition: shell.hpp:42
void publishDefault(const typename Event::PublishResources &publish)
Definition: mesos.hpp:3463
TOffer::Operation DESTROY_DISK(const TResource &source, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1607
TResource::ReservationInfo createDynamicReservationInfo(const std::string &role, const Option< std::string > &principal=None(), const Option< TLabels > &labels=None())
Definition: mesos.hpp:1079
TContainerInfo createContainerInfo(const Option< std::string > &imageName=None(), const std::vector< TVolume > &volumes={})
Definition: mesos.hpp:896
mesos::v1::scheduler::Event Event
Definition: mesos.hpp:2852
mesos::v1::Volume createVolumeSandboxPath(Args &&...args)
Definition: mesos.hpp:2050
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:2160
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:2695
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:3808
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:2075
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:2187
mesos::v1::scheduler::APIResult APIResult
Definition: mesos.hpp:2850
Definition: scheduler.hpp:186
mesos::v1::TaskGroupInfo createTaskGroupInfo(const std::vector< mesos::v1::TaskInfo > &tasks)
Definition: mesos.hpp:2117
#define CHECK_SOME(expression)
Definition: check.hpp:50
mesos::v1::Resource::ReservationInfo createStaticReservationInfo(const std::string &role)
Definition: mesos.hpp:2126
void start(process::Owned< mesos::internal::EndpointDetector > detector, ContentType contentType)
Definition: mesos.hpp:3291
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:2654
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:2251
void events(Mesos *mesos, std::queue< Event > events)
Definition: mesos.hpp:2743
mesos::v1::Image createDockerImage(Args &&...args)
Definition: mesos.hpp:2042
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:2067
void SetUp() override
Definition: utils.hpp:37
#define DEFAULT_CREDENTIAL
Definition: mesos.hpp:2505
TOffer::Operation SHRINK_VOLUME(const TResource &volume, const TValueScalar &subtract, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1533
TOffer::Operation DESTROY(const TResources &volumes, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1493
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:3904
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:2271
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:1442
std::string operator()(const ::testing::TestParamInfo< ParamExecutorType > &info) const
Definition: mesos.hpp:4064
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:3839
mesos::v1::scheduler::Call createCallReconcileOperations(const mesos::v1::FrameworkID &frameworkId, const std::vector< mesos::v1::scheduler::Call::ReconcileOperations::Operation > &operations={})
Definition: mesos.hpp:2445
const T & get() const &
Definition: option.hpp:119
process::http::Headers createBasicAuthHeaders(Args &&...args)
Definition: mesos.hpp:2216
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:4083
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:70
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:3356
Definition: executor.hpp:75
process::Future< Message > FutureHttp(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3788
mesos::v1::Parameters parameterize(Args &&...args)
Definition: mesos.hpp:2341
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:3583
void events(std::queue< Event > events)
Definition: mesos.hpp:3249
bool isDefaultExecutor() const
Definition: mesos.hpp:4089
mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(Args &&...args)
Definition: mesos.hpp:2178
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:4106
static ParamExecutorType commandExecutor()
Definition: mesos.hpp:4078
Basic model of an allocator: resources are allocated to a framework in the form of offers...
Definition: allocator.hpp:172
mesos::v1::executor::Call Call
Definition: mesos.hpp:3084
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:3009
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:3776
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:2677
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:3932
Definition: executor.hpp:48
void ExpectNoFutureHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3915
Type
Definition: capabilities.hpp:82
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:2420
mesos::v1::Offer::Operation CREATE(Args &&...args)
Definition: mesos.hpp:2261
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:953
process::Future< Nothing > send(const Call &call)
Definition: mesos.hpp:3533
std::string body
Definition: http.hpp:578
void start(process::Owned< mesos::internal::EndpointDetector > detector, ContentType contentType)
Definition: mesos.hpp:3522
uint64_t bytes() const
Definition: bytes.hpp:79
Definition: mesos.hpp:3615
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:1296
std::string body
Definition: message.hpp:27
process::Future< Nothing > send(const Call &call)
Definition: mesos.hpp:3282
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:3184
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:3057
ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
Definition: mesos.hpp:3130
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:1265
TOffer::Operation LAUNCH_GROUP(const TExecutorInfo &executorInfo, const TTaskGroupInfo &taskGroup)
Definition: mesos.hpp:1566
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:2548
static TCredential create()
Definition: mesos.hpp:581
void allocate(const std::string &role)
void ExpectNoFutureProtobufs(T t, From from, To to)
Definition: mesos.hpp:3894
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:3765
hashmap< std::string, double > convertToHashmap(Args &&...args)
Definition: mesos.hpp:2233
bool enabled()
Option< mesos::slave::ResourceEstimator * > resourceEstimator
Definition: mesos.hpp:211
TTaskGroupInfo createTaskGroupInfo(const std::vector< TTaskInfo > &tasks)
Definition: mesos.hpp:1057
Option< Resources > find(const Resources &targets) const
constexpr int FAILURE
Definition: decoder.hpp:50
Definition: mesos.hpp:2636
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:2302
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:2206
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:2348
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:2225
mesos::v1::scheduler::Response Response
Definition: mesos.hpp:2854
TOffer::Operation GROW_VOLUME(const TResource &volume, const TResource &addition, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1510
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:1583
~TestMesos() override
Definition: mesos.hpp:2821
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:3508
mesos::v1::Offer::Operation LAUNCH_GROUP(Args &&...args)
Definition: mesos.hpp:2310
mesos::v1::AgentID getAgentID(const mesos::v1::Offer &offer)
Definition: mesos.hpp:922
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:2661
mesos::v1::Offer::Operation GROW_VOLUME(Args &&...args)
Definition: mesos.hpp:2281
TOffer::Operation CREATE(const TResources &volumes, const Option< TOperationID > &operationId=None())
Definition: mesos.hpp:1476
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:2598
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:3876
mesos::v1::Resource::DiskInfo createDiskInfo(Args &&...args)
Definition: mesos.hpp:2152
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:3386
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:3086
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:2373
Try< std::set< std::string > > subsystems()
Definition: mesos.hpp:2516
void filter(Filter *filter)
virtual master::Flags CreateMasterFlags()
MATCHER_P(OffersHaveAnyResource, filter,"")
Definition: mesos.hpp:3952
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:2488