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