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