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