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  slave::Flags CreateSlaveFlags() override;
325  void SetUp() override;
326  void TearDown() override;
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  void SetUp() override
375  {
377  server->startNetwork();
378  }
379 
380  void TearDown() override
381  {
382  server->shutdownNetwork();
384  }
385 
386 protected:
387  MesosZooKeeperTest() : MesosTest(url) {}
388 
389  master::Flags CreateMasterFlags() override
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_DISK);
1409  operation.mutable_create_disk()->mutable_source()->CopyFrom(source);
1410  operation.mutable_create_disk()->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_DISK(const TResource& source)
1422 {
1423  typename TOffer::Operation operation;
1424  operation.set_type(TOffer::Operation::DESTROY_DISK);
1425  operation.mutable_destroy_disk()->mutable_source()->CopyFrom(source);
1426 
1427  return operation;
1428 }
1429 
1430 
1431 template <typename TParameters, typename TParameter>
1432 inline TParameters parameterize(const ACLs& acls)
1433 {
1434  TParameters parameters;
1435  TParameter* parameter = parameters.add_parameter();
1436  parameter->set_key("acls");
1437  parameter->set_value(std::string(jsonify(JSON::Protobuf(acls))));
1438 
1439  return parameters;
1440 }
1441 } // namespace common {
1442 
1443 
1444 // TODO(jmlvanre): Remove `inline` once we have adjusted all tests to
1445 // distinguish between `internal` and `v1`.
1446 inline namespace internal {
1447 template <typename... Args>
1448 inline ExecutorInfo createExecutorInfo(Args&&... args)
1449 {
1451  ExecutorInfo,
1452  ExecutorID,
1453  Resources,
1454  CommandInfo,
1455  FrameworkID>(std::forward<Args>(args)...);
1456 }
1457 
1458 
1459 // We specify the argument to allow brace initialized construction.
1460 inline CommandInfo createCommandInfo(
1461  const Option<std::string>& value = None(),
1462  const std::vector<std::string>& arguments = {})
1463 {
1464  return common::createCommandInfo<CommandInfo>(value, arguments);
1465 }
1466 
1467 
1468 // Almost a direct snippet of code at the bottom of `Slave::launchExecutor`.
1469 inline mesos::slave::ContainerConfig createContainerConfig(
1470  const Option<TaskInfo>& taskInfo,
1471  const ExecutorInfo& executorInfo,
1472  const std::string& sandboxDirectory,
1473  const Option<std::string>& user = None())
1474 {
1475  mesos::slave::ContainerConfig containerConfig;
1476  containerConfig.mutable_executor_info()->CopyFrom(executorInfo);
1477  containerConfig.mutable_command_info()->CopyFrom(executorInfo.command());
1478  containerConfig.mutable_resources()->CopyFrom(executorInfo.resources());
1479  containerConfig.set_directory(sandboxDirectory);
1480 
1481  if (user.isSome()) {
1482  containerConfig.set_user(user.get());
1483  }
1484 
1485  if (taskInfo.isSome()) {
1486  containerConfig.mutable_task_info()->CopyFrom(taskInfo.get());
1487 
1488  if (taskInfo->has_container()) {
1489  containerConfig.mutable_container_info()->CopyFrom(taskInfo->container());
1490  }
1491  } else {
1492  if (executorInfo.has_container()) {
1493  containerConfig.mutable_container_info()
1494  ->CopyFrom(executorInfo.container());
1495  }
1496  }
1497 
1498  return containerConfig;
1499 }
1500 
1501 
1502 // Almost a direct snippet of code in `Slave::Http::_launchNestedContainer`.
1503 inline mesos::slave::ContainerConfig createContainerConfig(
1504  const CommandInfo& commandInfo,
1505  const Option<ContainerInfo>& containerInfo = None(),
1506  const Option<mesos::slave::ContainerClass>& containerClass = None(),
1507  const Option<std::string>& user = None())
1508 {
1509  mesos::slave::ContainerConfig containerConfig;
1510  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1511 
1512  if (user.isSome()) {
1513  containerConfig.set_user(user.get());
1514  }
1515 
1516  if (containerInfo.isSome()) {
1517  containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
1518  }
1519 
1520  if (containerClass.isSome()) {
1521  containerConfig.set_container_class(containerClass.get());
1522  }
1523 
1524  return containerConfig;
1525 }
1526 
1527 
1528 // Helper for creating standalone container configs.
1529 inline mesos::slave::ContainerConfig createContainerConfig(
1530  const CommandInfo& commandInfo,
1531  const std::string& resources,
1532  const std::string& sandboxDirectory,
1533  const Option<ContainerInfo>& containerInfo = None(),
1534  const Option<std::string>& user = None())
1535 {
1536  mesos::slave::ContainerConfig containerConfig;
1537  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
1538  containerConfig.mutable_resources()->CopyFrom(
1539  Resources::parse(resources).get());
1540 
1541  containerConfig.set_directory(sandboxDirectory);
1542 
1543  if (user.isSome()) {
1544  containerConfig.set_user(user.get());
1545  }
1546 
1547  if (containerInfo.isSome()) {
1548  containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
1549  }
1550 
1551  return containerConfig;
1552 }
1553 
1554 
1555 template <typename... Args>
1556 inline Image createDockerImage(Args&&... args)
1557 {
1558  return common::createDockerImage<Image>(std::forward<Args>(args)...);
1559 }
1560 
1561 
1562 template <typename... Args>
1563 inline Volume createVolumeSandboxPath(Args&&... args)
1564 {
1565  return common::createVolumeSandboxPath<Volume>(std::forward<Args>(args)...);
1566 }
1567 
1568 
1569 template <typename... Args>
1570 inline Volume createVolumeHostPath(Args&&... args)
1571 {
1572  return common::createVolumeHostPath<Volume, MountPropagation>(
1573  std::forward<Args>(args)...);
1574 }
1575 
1576 
1577 template <typename... Args>
1578 inline Volume createVolumeFromDockerImage(Args&&... args)
1579 {
1580  return common::createVolumeFromDockerImage<Volume, Image>(
1581  std::forward<Args>(args)...);
1582 }
1583 
1584 
1585 template <typename... Args>
1586 inline NetworkInfo createNetworkInfo(Args&&... args)
1587 {
1588  return common::createNetworkInfo<NetworkInfo>(std::forward<Args>(args)...);
1589 }
1590 
1591 
1592 // We specify the argument to allow brace initialized construction.
1593 inline ContainerInfo createContainerInfo(
1594  const Option<std::string>& imageName = None(),
1595  const std::vector<Volume>& volumes = {})
1596 {
1597  return common::createContainerInfo<ContainerInfo, Volume, Image>(
1598  imageName,
1599  volumes);
1600 }
1601 
1602 
1603 template <typename... Args>
1604 inline TaskInfo createTask(Args&&... args)
1605 {
1606  return common::createTask<
1607  TaskInfo,
1608  ExecutorID,
1609  SlaveID,
1610  Resources,
1611  ExecutorInfo,
1612  CommandInfo,
1613  Offer>(std::forward<Args>(args)...);
1614 }
1615 
1616 
1617 // We specify the argument to allow brace initialized construction.
1618 inline TaskGroupInfo createTaskGroupInfo(const std::vector<TaskInfo>& tasks)
1619 {
1620  return common::createTaskGroupInfo<TaskGroupInfo, TaskInfo>(tasks);
1621 }
1622 
1623 
1624 inline Resource::ReservationInfo createStaticReservationInfo(
1625  const std::string& role)
1626 {
1627  return common::createStaticReservationInfo<Resource>(role);
1628 }
1629 
1630 
1631 inline Resource::ReservationInfo createDynamicReservationInfo(
1632  const std::string& role,
1633  const Option<std::string>& principal = None(),
1634  const Option<Labels>& labels = None())
1635 {
1636  return common::createDynamicReservationInfo<Resource, Labels>(
1637  role, principal, labels);
1638 }
1639 
1640 
1641 template <typename... Args>
1642 inline Resource createReservedResource(Args&&... args)
1643 {
1644  return common::createReservedResource<Resource, Resources>(
1645  std::forward<Args>(args)...);
1646 }
1647 
1648 
1649 template <typename... Args>
1650 inline Resource::DiskInfo createDiskInfo(Args&&... args)
1651 {
1652  return common::createDiskInfo<Resource, Volume>(std::forward<Args>(args)...);
1653 }
1654 
1655 
1656 template <typename... Args>
1657 inline Resource::DiskInfo::Source createDiskSourcePath(Args&&... args)
1658 {
1659  return common::createDiskSourcePath<Resource>(std::forward<Args>(args)...);
1660 }
1661 
1662 
1663 template <typename... Args>
1664 inline Resource::DiskInfo::Source createDiskSourceMount(Args&&... args)
1665 {
1666  return common::createDiskSourceMount<Resource>(std::forward<Args>(args)...);
1667 }
1668 
1669 
1670 template <typename... Args>
1671 inline Resource::DiskInfo::Source createDiskSourceBlock(Args&&... args)
1672 {
1673  return common::createDiskSourceBlock<Resource>(std::forward<Args>(args)...);
1674 }
1675 
1676 
1677 template <typename... Args>
1678 inline Resource::DiskInfo::Source createDiskSourceRaw(Args&&... args)
1679 {
1680  return common::createDiskSourceRaw<Resource>(std::forward<Args>(args)...);
1681 }
1682 
1683 
1684 template <typename... Args>
1685 inline Resource createDiskResource(Args&&... args)
1686 {
1687  return common::createDiskResource<Resource, Resources, Volume>(
1688  std::forward<Args>(args)...);
1689 }
1690 
1691 
1692 template <typename... Args>
1693 inline Resource createPersistentVolume(Args&&... args)
1694 {
1695  return common::createPersistentVolume<Resource, Resources, Volume>(
1696  std::forward<Args>(args)...);
1697 }
1698 
1699 
1700 template <typename... Args>
1702 {
1703  return common::createBasicAuthHeaders<Credential>(
1704  std::forward<Args>(args)...);
1705 }
1706 
1707 
1708 template <typename... Args>
1709 inline google::protobuf::RepeatedPtrField<WeightInfo> createWeightInfos(
1710  Args&&... args)
1711 {
1712  return common::createWeightInfos<WeightInfo>(std::forward<Args>(args)...);
1713 }
1714 
1715 
1716 template <typename... Args>
1718 {
1719  return common::convertToHashmap<WeightInfo>(std::forward<Args>(args)...);
1720 }
1721 
1722 
1723 template <typename... Args>
1724 inline DomainInfo createDomainInfo(Args&&... args)
1725 {
1726  return common::createDomainInfo<DomainInfo>(std::forward<Args>(args)...);
1727 }
1728 
1729 
1730 template <typename... Args>
1731 inline Offer::Operation RESERVE(Args&&... args)
1732 {
1733  return common::RESERVE<Resources, Offer>(std::forward<Args>(args)...);
1734 }
1735 
1736 
1737 template <typename... Args>
1738 inline Offer::Operation UNRESERVE(Args&&... args)
1739 {
1740  return common::UNRESERVE<Resources, Offer>(std::forward<Args>(args)...);
1741 }
1742 
1743 
1744 template <typename... Args>
1745 inline Offer::Operation CREATE(Args&&... args)
1746 {
1747  return common::CREATE<Resources, Offer>(std::forward<Args>(args)...);
1748 }
1749 
1750 
1751 template <typename... Args>
1752 inline Offer::Operation DESTROY(Args&&... args)
1753 {
1754  return common::DESTROY<Resources, Offer>(std::forward<Args>(args)...);
1755 }
1756 
1757 
1758 template <typename... Args>
1759 inline Offer::Operation GROW_VOLUME(Args&&... args)
1760 {
1761  return common::GROW_VOLUME<Resource, Offer>(std::forward<Args>(args)...);
1762 }
1763 
1764 
1765 template <typename... Args>
1766 inline Offer::Operation SHRINK_VOLUME(Args&&... args)
1767 {
1768  return common::SHRINK_VOLUME<Resource, Offer>(std::forward<Args>(args)...);
1769 }
1770 
1771 
1772 // We specify the argument to allow brace initialized construction.
1773 inline Offer::Operation LAUNCH(const std::vector<TaskInfo>& tasks)
1774 {
1775  return common::LAUNCH<Offer, TaskInfo>(tasks);
1776 }
1777 
1778 
1779 template <typename... Args>
1780 inline Offer::Operation LAUNCH_GROUP(Args&&... args)
1781 {
1782  return common::LAUNCH_GROUP<ExecutorInfo, TaskGroupInfo, Offer>(
1783  std::forward<Args>(args)...);
1784 }
1785 
1786 
1787 template <typename... Args>
1788 inline Offer::Operation CREATE_DISK(Args&&... args)
1789 {
1790  return common::CREATE_DISK<Resource,
1792  Offer>(std::forward<Args>(args)...);
1793 }
1794 
1795 
1796 template <typename... Args>
1797 inline Offer::Operation DESTROY_DISK(Args&&... args)
1798 {
1799  return common::DESTROY_DISK<Resource, Offer>(std::forward<Args>(args)...);
1800 }
1801 
1802 
1803 template <typename... Args>
1804 inline Parameters parameterize(Args&&... args)
1805 {
1806  return common::parameterize<Parameters, Parameter>(
1807  std::forward<Args>(args)...);
1808 }
1809 } // namespace internal {
1810 
1811 
1812 namespace v1 {
1813 template <typename... Args>
1814 inline mesos::v1::ExecutorInfo createExecutorInfo(Args&&... args)
1815 {
1817  mesos::v1::ExecutorInfo,
1818  mesos::v1::ExecutorID,
1820  mesos::v1::CommandInfo,
1821  mesos::v1::FrameworkID>(std::forward<Args>(args)...);
1822 }
1823 
1824 
1825 // We specify the argument to allow brace initialized construction.
1826 inline mesos::v1::CommandInfo createCommandInfo(
1827  const Option<std::string>& value = None(),
1828  const std::vector<std::string>& arguments = {})
1829 {
1830  return common::createCommandInfo<mesos::v1::CommandInfo>(value, arguments);
1831 }
1832 
1833 
1834 template <typename... Args>
1835 inline mesos::v1::Image createDockerImage(Args&&... args)
1836 {
1837  return common::createDockerImage<mesos::v1::Image>(
1838  std::forward<Args>(args)...);
1839 }
1840 
1841 
1842 template <typename... Args>
1843 inline mesos::v1::Volume createVolumeSandboxPath(Args&&... args)
1844 {
1845  return common::createVolumeSandboxPath<mesos::v1::Volume>(
1846  std::forward<Args>(args)...);
1847 }
1848 
1849 
1850 template <typename... Args>
1851 inline mesos::v1::Volume createVolumeHostPath(Args&&... args)
1852 {
1854  mesos::v1::Volume,
1855  mesos::v1::MountPropagation>(std::forward<Args>(args)...);
1856 }
1857 
1858 
1859 template <typename... Args>
1860 inline mesos::v1::Volume createVolumeFromDockerImage(Args&&... args)
1861 {
1863  mesos::v1::Volume, mesos::v1::Image>(std::forward<Args>(args)...);
1864 }
1865 
1866 
1867 template <typename... Args>
1868 inline mesos::v1::NetworkInfo createNetworkInfo(Args&&... args)
1869 {
1870  return common::createNetworkInfo<mesos::v1::NetworkInfo>(
1871  std::forward<Args>(args)...);
1872 }
1873 
1874 
1875 // We specify the argument to allow brace initialized construction.
1876 inline mesos::v1::ContainerInfo createContainerInfo(
1877  const Option<std::string>& imageName = None(),
1878  const std::vector<mesos::v1::Volume>& volumes = {})
1879 {
1881  mesos::v1::ContainerInfo, mesos::v1::Volume, mesos::v1::Image>(
1882  imageName, volumes);
1883 }
1884 
1885 
1886 template <typename... Args>
1887 inline mesos::v1::TaskInfo createTask(Args&&... args)
1888 {
1889  return common::createTask<
1890  mesos::v1::TaskInfo,
1891  mesos::v1::ExecutorID,
1892  mesos::v1::AgentID,
1894  mesos::v1::ExecutorInfo,
1895  mesos::v1::CommandInfo,
1896  mesos::v1::Offer>(std::forward<Args>(args)...);
1897 }
1898 
1899 
1900 // We specify the argument to allow brace initialized construction.
1901 inline mesos::v1::TaskGroupInfo createTaskGroupInfo(
1902  const std::vector<mesos::v1::TaskInfo>& tasks)
1903 {
1905  mesos::v1::TaskGroupInfo,
1906  mesos::v1::TaskInfo>(tasks);
1907 }
1908 
1909 
1910 inline mesos::v1::Resource::ReservationInfo createStaticReservationInfo(
1911  const std::string& role)
1912 {
1913  return common::createStaticReservationInfo<mesos::v1::Resource>(role);
1914 }
1915 
1916 
1917 inline mesos::v1::Resource::ReservationInfo createDynamicReservationInfo(
1918  const std::string& role,
1919  const Option<std::string>& principal = None(),
1920  const Option<mesos::v1::Labels>& labels = None())
1921 {
1923  mesos::v1::Resource, mesos::v1::Labels>(role, principal, labels);
1924 }
1925 
1926 
1927 template <typename... Args>
1928 inline mesos::v1::Resource createReservedResource(Args&&... args)
1929 {
1931  mesos::v1::Resource, mesos::v1::Resources>(std::forward<Args>(args)...);
1932 }
1933 
1934 
1935 template <typename... Args>
1936 inline mesos::v1::Resource::DiskInfo createDiskInfo(Args&&... args)
1937 {
1938  return common::createDiskInfo<mesos::v1::Resource, mesos::v1::Volume>(
1939  std::forward<Args>(args)...);
1940 }
1941 
1942 
1943 template <typename... Args>
1944 inline mesos::v1::Resource::DiskInfo::Source createDiskSourcePath(
1945  Args&&... args)
1946 {
1947  return common::createDiskSourcePath<mesos::v1::Resource>(
1948  std::forward<Args>(args)...);
1949 }
1950 
1951 
1952 template <typename... Args>
1953 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceMount(
1954  Args&&... args)
1955 {
1956  return common::createDiskSourceMount<mesos::v1::Resource>(
1957  std::forward<Args>(args)...);
1958 }
1959 
1960 
1961 template <typename... Args>
1962 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(
1963  Args&&... args)
1964 {
1965  return common::createDiskSourceBlock<mesos::v1::Resource>(
1966  std::forward<Args>(args)...);
1967 }
1968 
1969 
1970 template <typename... Args>
1971 inline mesos::v1::Resource::DiskInfo::Source createDiskSourceRaw(
1972  Args&&... args)
1973 {
1974  return common::createDiskSourceRaw<mesos::v1::Resource>(
1975  std::forward<Args>(args)...);
1976 }
1977 
1978 
1979 template <typename... Args>
1980 inline mesos::v1::Resource createDiskResource(Args&&... args)
1981 {
1983  mesos::v1::Resource,
1985  mesos::v1::Volume>(std::forward<Args>(args)...);
1986 }
1987 
1988 
1989 template <typename... Args>
1990 inline mesos::v1::Resource createPersistentVolume(Args&&... args)
1991 {
1993  mesos::v1::Resource,
1995  mesos::v1::Volume>(std::forward<Args>(args)...);
1996 }
1997 
1998 
1999 template <typename... Args>
2001 {
2002  return common::createBasicAuthHeaders<mesos::v1::Credential>(
2003  std::forward<Args>(args)...);
2004 }
2005 
2006 
2007 template <typename... Args>
2008 inline google::protobuf::RepeatedPtrField<
2009  mesos::v1::WeightInfo> createWeightInfos(Args&&... args)
2010 {
2011  return common::createWeightInfos<mesos::v1::WeightInfo>(
2012  std::forward<Args>(args)...);
2013 }
2014 
2015 
2016 template <typename... Args>
2018 {
2019  return common::convertToHashmap<mesos::v1::WeightInfo>(
2020  std::forward<Args>(args)...);
2021 }
2022 
2023 
2024 template <typename... Args>
2025 inline mesos::v1::Offer::Operation RESERVE(Args&&... args)
2026 {
2027  return common::RESERVE<mesos::v1::Resources, mesos::v1::Offer>(
2028  std::forward<Args>(args)...);
2029 }
2030 
2031 
2032 template <typename... Args>
2034 {
2035  return common::UNRESERVE<mesos::v1::Resources, mesos::v1::Offer>(
2036  std::forward<Args>(args)...);
2037 }
2038 
2039 
2040 template <typename... Args>
2041 inline mesos::v1::Offer::Operation CREATE(Args&&... args)
2042 {
2043  return common::CREATE<mesos::v1::Resources, mesos::v1::Offer>(
2044  std::forward<Args>(args)...);
2045 }
2046 
2047 
2048 template <typename... Args>
2049 inline mesos::v1::Offer::Operation DESTROY(Args&&... args)
2050 {
2051  return common::DESTROY<mesos::v1::Resources, mesos::v1::Offer>(
2052  std::forward<Args>(args)...);
2053 }
2054 
2055 
2056 template <typename... Args>
2058 {
2059  return common::GROW_VOLUME<mesos::v1::Resource, mesos::v1::Offer>(
2060  std::forward<Args>(args)...);
2061 }
2062 
2063 
2064 template <typename... Args>
2066 {
2067  return common::SHRINK_VOLUME<mesos::v1::Resource, mesos::v1::Offer>(
2068  std::forward<Args>(args)...);
2069 }
2070 
2071 
2072 // We specify the argument to allow brace initialized construction.
2074  const std::vector<mesos::v1::TaskInfo>& tasks)
2075 {
2076  return common::LAUNCH<mesos::v1::Offer, mesos::v1::TaskInfo>(tasks);
2077 }
2078 
2079 
2080 template <typename... Args>
2082 {
2083  return common::LAUNCH_GROUP<
2084  mesos::v1::ExecutorInfo,
2085  mesos::v1::TaskGroupInfo,
2086  mesos::v1::Offer>(std::forward<Args>(args)...);
2087 }
2088 
2089 
2090 template <typename... Args>
2092 {
2093  return common::CREATE_DISK<mesos::v1::Resource,
2095  mesos::v1::Offer>(
2096  std::forward<Args>(args)...);
2097 }
2098 
2099 
2100 template <typename... Args>
2102 {
2103  return common::DESTROY_DISK<mesos::v1::Resource, mesos::v1::Offer>(
2104  std::forward<Args>(args)...);
2105 }
2106 
2107 
2108 template <typename... Args>
2109 inline mesos::v1::Parameters parameterize(Args&&... args)
2110 {
2111  return common::parameterize<mesos::v1::Parameters, mesos::v1::Parameter>(
2112  std::forward<Args>(args)...);
2113 }
2114 
2115 
2117  const mesos::v1::FrameworkID& frameworkId,
2118  const mesos::v1::Offer& offer,
2119  const std::vector<mesos::v1::Offer::Operation>& operations,
2121 {
2123  call.set_type(mesos::v1::scheduler::Call::ACCEPT);
2124  call.mutable_framework_id()->CopyFrom(frameworkId);
2125 
2126  mesos::v1::scheduler::Call::Accept* accept = call.mutable_accept();
2127  accept->add_offer_ids()->CopyFrom(offer.id());
2128 
2129  foreach (const mesos::v1::Offer::Operation& operation, operations) {
2130  accept->add_operations()->CopyFrom(operation);
2131  }
2132 
2133  if (filters.isSome()) {
2134  accept->mutable_filters()->CopyFrom(filters.get());
2135  }
2136 
2137  return call;
2138 }
2139 
2140 
2142  const mesos::v1::FrameworkID& frameworkId,
2143  const mesos::v1::AgentID& agentId,
2144  const mesos::v1::scheduler::Event::Update& update)
2145 {
2147  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE);
2148  call.mutable_framework_id()->CopyFrom(frameworkId);
2149 
2150  mesos::v1::scheduler::Call::Acknowledge* acknowledge =
2151  call.mutable_acknowledge();
2152 
2153  acknowledge->mutable_task_id()->CopyFrom(
2154  update.status().task_id());
2155 
2156  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2157  acknowledge->set_uuid(update.status().uuid());
2158 
2159  return call;
2160 }
2161 
2162 
2164  const mesos::v1::FrameworkID& frameworkId,
2165  const mesos::v1::AgentID& agentId,
2166  const mesos::v1::ResourceProviderID& resourceProviderId,
2167  const mesos::v1::scheduler::Event::UpdateOperationStatus& update)
2168 {
2170  call.set_type(mesos::v1::scheduler::Call::ACKNOWLEDGE_OPERATION_STATUS);
2171  call.mutable_framework_id()->CopyFrom(frameworkId);
2172 
2173  mesos::v1::scheduler::Call::AcknowledgeOperationStatus* acknowledge =
2174  call.mutable_acknowledge_operation_status();
2175 
2176  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2177  acknowledge->mutable_resource_provider_id()->CopyFrom(resourceProviderId);
2178  acknowledge->set_uuid(update.status().uuid().value());
2179  acknowledge->mutable_operation_id()->CopyFrom(update.status().operation_id());
2180 
2181  return call;
2182 }
2183 
2184 
2186  const mesos::v1::FrameworkID& frameworkId,
2187  const mesos::v1::TaskID& taskId,
2188  const Option<mesos::v1::AgentID>& agentId = None(),
2189  const Option<mesos::v1::KillPolicy>& killPolicy = None())
2190 {
2192  call.set_type(mesos::v1::scheduler::Call::KILL);
2193  call.mutable_framework_id()->CopyFrom(frameworkId);
2194 
2195  mesos::v1::scheduler::Call::Kill* kill = call.mutable_kill();
2196  kill->mutable_task_id()->CopyFrom(taskId);
2197 
2198  if (agentId.isSome()) {
2199  kill->mutable_agent_id()->CopyFrom(agentId.get());
2200  }
2201 
2202  if (killPolicy.isSome()) {
2203  kill->mutable_kill_policy()->CopyFrom(killPolicy.get());
2204  }
2205 
2206  return call;
2207 }
2208 
2209 
2211  const mesos::v1::FrameworkID& frameworkId,
2212  const std::vector<
2214  operations = {})
2215 {
2217  call.set_type(mesos::v1::scheduler::Call::RECONCILE_OPERATIONS);
2218  call.mutable_framework_id()->CopyFrom(frameworkId);
2219 
2220  mesos::v1::scheduler::Call::ReconcileOperations* reconcile =
2221  call.mutable_reconcile_operations();
2222 
2223  foreach (
2225  operation,
2226  operations) {
2227  reconcile->add_operations()->CopyFrom(operation);
2228  }
2229 
2230  return call;
2231 }
2232 
2233 
2235  const mesos::v1::FrameworkInfo& frameworkInfo,
2236  const Option<mesos::v1::FrameworkID>& frameworkId = None())
2237 {
2239  call.set_type(mesos::v1::scheduler::Call::SUBSCRIBE);
2240 
2241  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2242 
2243  if (frameworkId.isSome()) {
2244  call.mutable_framework_id()->CopyFrom(frameworkId.get());
2245  }
2246 
2247  return call;
2248 }
2249 
2250 } // namespace v1 {
2251 
2252 
2253 inline mesos::Environment createEnvironment(
2255 {
2256  mesos::Environment environment;
2257  foreachpair (const std::string& key, const std::string& value, map) {
2258  mesos::Environment::Variable* variable = environment.add_variables();
2259  variable->set_name(key);
2260  variable->set_value(value);
2261  }
2262  return environment;
2263 }
2264 
2265 
2266 // Macros to get/create (default) ExecutorInfos and FrameworkInfos.
2267 #define DEFAULT_EXECUTOR_INFO createExecutorInfo("default", "exit 1")
2268 
2269 
2270 #define DEFAULT_CREDENTIAL DefaultCredential::create()
2271 #define DEFAULT_CREDENTIAL_2 DefaultCredential2::create()
2272 
2273 
2274 #define DEFAULT_FRAMEWORK_INFO DefaultFrameworkInfo::create()
2275 
2276 
2277 #define DEFAULT_EXECUTOR_ID DEFAULT_EXECUTOR_INFO.executor_id()
2278 
2279 
2280 // Definition of a mock Scheduler to be used in tests with gmock.
2281 class MockScheduler : public Scheduler
2282 {
2283 public:
2284  MockScheduler();
2285  ~MockScheduler() override;
2286 
2287  MOCK_METHOD3(registered, void(SchedulerDriver*,
2288  const FrameworkID&,
2289  const MasterInfo&));
2290  MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
2291  MOCK_METHOD1(disconnected, void(SchedulerDriver*));
2292  MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
2293  const std::vector<Offer>&));
2294  MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
2295  MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
2296  MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
2297  const ExecutorID&,
2298  const SlaveID&,
2299  const std::string&));
2300  MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
2301  MOCK_METHOD4(executorLost, void(SchedulerDriver*,
2302  const ExecutorID&,
2303  const SlaveID&,
2304  int));
2305  MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
2306 };
2307 
2308 // For use with a MockScheduler, for example:
2309 // EXPECT_CALL(sched, resourceOffers(_, _))
2310 // .WillOnce(LaunchTasks(EXECUTOR, TASKS, CPUS, MEM, ROLE));
2311 // Launches up to TASKS no-op tasks, if possible,
2312 // each with CPUS cpus and MEM memory and EXECUTOR executor.
2313 ACTION_P5(LaunchTasks, executor, tasks, cpus, mem, role)
2314 {
2315  SchedulerDriver* driver = arg0;
2316  std::vector<Offer> offers = arg1;
2317  int numTasks = tasks;
2318 
2319  int launched = 0;
2320  for (size_t i = 0; i < offers.size(); i++) {
2321  const Offer& offer = offers[i];
2322 
2323  Resources taskResources = Resources::parse(
2324  "cpus:" + stringify(cpus) + ";mem:" + stringify(mem)).get();
2325 
2326  if (offer.resources_size() > 0 &&
2327  offer.resources(0).has_allocation_info()) {
2328  taskResources.allocate(role);
2329  }
2330 
2331  int nextTaskId = 0;
2332  std::vector<TaskInfo> tasks;
2333  Resources remaining = offer.resources();
2334 
2335  while (remaining.toUnreserved().contains(taskResources) &&
2336  launched < numTasks) {
2337  TaskInfo task;
2338  task.set_name("TestTask");
2339  task.mutable_task_id()->set_value(stringify(nextTaskId++));
2340  task.mutable_slave_id()->MergeFrom(offer.slave_id());
2341  task.mutable_executor()->MergeFrom(executor);
2342 
2343  Option<Resources> resources = remaining.find(
2344  role == std::string("*")
2345  ? taskResources
2346  : taskResources.pushReservation(createStaticReservationInfo(role)));
2347 
2348  CHECK_SOME(resources);
2349 
2350  task.mutable_resources()->MergeFrom(resources.get());
2351  remaining -= resources.get();
2352 
2353  tasks.push_back(task);
2354  launched++;
2355  }
2356 
2357  driver->launchTasks(offer.id(), tasks);
2358  }
2359 }
2360 
2361 
2362 // Like LaunchTasks, but decline the entire offer and
2363 // don't launch any tasks.
2364 ACTION(DeclineOffers)
2365 {
2366  SchedulerDriver* driver = arg0;
2367  std::vector<Offer> offers = arg1;
2368 
2369  for (size_t i = 0; i < offers.size(); i++) {
2370  driver->declineOffer(offers[i].id());
2371  }
2372 }
2373 
2374 
2375 // Like DeclineOffers, but takes a custom filters object.
2376 ACTION_P(DeclineOffers, filters)
2377 {
2378  SchedulerDriver* driver = arg0;
2379  std::vector<Offer> offers = arg1;
2380 
2381  for (size_t i = 0; i < offers.size(); i++) {
2382  driver->declineOffer(offers[i].id(), filters);
2383  }
2384 }
2385 
2386 
2387 // For use with a MockScheduler, for example:
2388 // process::Queue<Offer> offers;
2389 // EXPECT_CALL(sched, resourceOffers(_, _))
2390 // .WillRepeatedly(EnqueueOffers(&offers));
2391 // Enqueues all received offers into the provided queue.
2392 ACTION_P(EnqueueOffers, queue)
2393 {
2394  std::vector<Offer> offers = arg1;
2395  foreach (const Offer& offer, offers) {
2396  queue->put(offer);
2397  }
2398 }
2399 
2400 
2401 // Definition of a mock Executor to be used in tests with gmock.
2402 class MockExecutor : public Executor
2403 {
2404 public:
2405  MockExecutor(const ExecutorID& _id);
2406  ~MockExecutor() override;
2407 
2408  MOCK_METHOD4(registered, void(ExecutorDriver*,
2409  const ExecutorInfo&,
2410  const FrameworkInfo&,
2411  const SlaveInfo&));
2412  MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
2413  MOCK_METHOD1(disconnected, void(ExecutorDriver*));
2414  MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
2415  MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
2416  MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
2417  MOCK_METHOD1(shutdown, void(ExecutorDriver*));
2418  MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
2419 
2420  const ExecutorID id;
2421 };
2422 
2423 
2425 {
2426 public:
2428  Scheduler* scheduler,
2431  scheduler,
2433  "",
2434  true,
2436  {
2437  // No-op destructor as _detector lives on the stack.
2438  detector =
2439  std::shared_ptr<mesos::master::detector::MasterDetector>(
2440  _detector, [](mesos::master::detector::MasterDetector*) {});
2441  }
2442 
2444  Scheduler* scheduler,
2446  const FrameworkInfo& framework,
2447  bool implicitAcknowledgements = true)
2449  scheduler,
2450  framework,
2451  "",
2452  implicitAcknowledgements,
2454  {
2455  // No-op destructor as _detector lives on the stack.
2456  detector =
2457  std::shared_ptr<mesos::master::detector::MasterDetector>(
2458  _detector, [](mesos::master::detector::MasterDetector*) {});
2459  }
2460 
2462  Scheduler* scheduler,
2464  const FrameworkInfo& framework,
2465  bool implicitAcknowledgements,
2466  const Credential& credential)
2468  scheduler,
2469  framework,
2470  "",
2471  implicitAcknowledgements,
2472  credential)
2473  {
2474  // No-op destructor as _detector lives on the stack.
2475  detector =
2476  std::shared_ptr<mesos::master::detector::MasterDetector>(
2477  _detector, [](mesos::master::detector::MasterDetector*) {});
2478  }
2479 };
2480 
2481 
2482 namespace scheduler {
2483 
2484 // A generic mock HTTP scheduler to be used in tests with gmock.
2485 template <typename Mesos, typename Event>
2487 {
2488 public:
2489  MOCK_METHOD1_T(connected, void(Mesos*));
2490  MOCK_METHOD1_T(disconnected, void(Mesos*));
2491  MOCK_METHOD1_T(heartbeat, void(Mesos*));
2492  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
2493  MOCK_METHOD2_T(offers, void(Mesos*, const typename Event::Offers&));
2494  MOCK_METHOD2_T(
2495  inverseOffers,
2496  void(Mesos*, const typename Event::InverseOffers&));
2497  MOCK_METHOD2_T(rescind, void(Mesos*, const typename Event::Rescind&));
2498  MOCK_METHOD2_T(
2499  rescindInverseOffers,
2500  void(Mesos*, const typename Event::RescindInverseOffer&));
2501  MOCK_METHOD2_T(update, void(Mesos*, const typename Event::Update&));
2502  MOCK_METHOD2_T(
2503  updateOperationStatus,
2504  void(Mesos*, const typename Event::UpdateOperationStatus&));
2505  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
2506  MOCK_METHOD2_T(failure, void(Mesos*, const typename Event::Failure&));
2507  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
2508 
2509  void events(Mesos* mesos, std::queue<Event> events)
2510  {
2511  while (!events.empty()) {
2512  Event event = std::move(events.front());
2513  events.pop();
2514 
2515  switch (event.type()) {
2516  case Event::SUBSCRIBED:
2517  subscribed(mesos, event.subscribed());
2518  break;
2519  case Event::OFFERS:
2520  offers(mesos, event.offers());
2521  break;
2522  case Event::INVERSE_OFFERS:
2523  inverseOffers(mesos, event.inverse_offers());
2524  break;
2525  case Event::RESCIND:
2526  rescind(mesos, event.rescind());
2527  break;
2528  case Event::RESCIND_INVERSE_OFFER:
2529  rescindInverseOffers(mesos, event.rescind_inverse_offer());
2530  break;
2531  case Event::UPDATE:
2532  update(mesos, event.update());
2533  break;
2534  case Event::UPDATE_OPERATION_STATUS:
2535  updateOperationStatus(mesos, event.update_operation_status());
2536  break;
2537  case Event::MESSAGE:
2538  message(mesos, event.message());
2539  break;
2540  case Event::FAILURE:
2541  failure(mesos, event.failure());
2542  break;
2543  case Event::ERROR:
2544  error(mesos, event.error());
2545  break;
2546  case Event::HEARTBEAT:
2547  heartbeat(mesos);
2548  break;
2549  case Event::UNKNOWN:
2550  LOG(FATAL) << "Received unexpected UNKNOWN event";
2551  break;
2552  }
2553  }
2554  }
2555 };
2556 
2557 
2558 // A generic testing interface for the scheduler library that can be used to
2559 // test the library across various versions.
2560 template <typename Mesos, typename Event>
2561 class TestMesos : public Mesos
2562 {
2563 public:
2565  const std::string& master,
2566  ContentType contentType,
2567  const std::shared_ptr<MockHTTPScheduler<Mesos, Event>>& scheduler,
2568  const Option<std::shared_ptr<mesos::master::detector::MasterDetector>>&
2569  detector = None())
2570  : Mesos(
2571  master,
2572  contentType,
2573  lambda::bind(&MockHTTPScheduler<Mesos, Event>::connected,
2574  scheduler,
2575  this),
2576  lambda::bind(&MockHTTPScheduler<Mesos, Event>::disconnected,
2577  scheduler,
2578  this),
2579  lambda::bind(&MockHTTPScheduler<Mesos, Event>::events,
2580  scheduler,
2581  this,
2582  lambda::_1),
2583  v1::DEFAULT_CREDENTIAL,
2584  detector) {}
2585 
2586  ~TestMesos() override
2587  {
2588  // Since the destructor for `TestMesos` is invoked first, the library can
2589  // make more callbacks to the `scheduler` object before the `Mesos` (base
2590  // class) destructor is invoked. To prevent this, we invoke `stop()` here
2591  // to explicitly stop the library.
2592  this->stop();
2593 
2594  bool paused = process::Clock::paused();
2595 
2596  // Need to settle the Clock to ensure that all the pending async callbacks
2597  // with references to `this` and `scheduler` queued on libprocess are
2598  // executed before the object is destructed.
2601 
2602  // Return the Clock to its original state.
2603  if (!paused) {
2605  }
2606  }
2607 };
2608 
2609 } // namespace scheduler {
2610 
2611 
2612 namespace v1 {
2613 namespace scheduler {
2614 
2620 
2621 
2625 
2626 
2627 // This matcher is used to match an offer event that contains a vector of offers
2628 // having any resource that passes the filter.
2629 MATCHER_P(OffersHaveAnyResource, filter, "")
2630 {
2631  foreach (const Offer& offer, arg.offers()) {
2632  foreach (const Resource& resource, offer.resources()) {
2633  if (filter(resource)) {
2634  return true;
2635  }
2636  }
2637  }
2638 
2639  return false;
2640 }
2641 
2642 
2643 // Like LaunchTasks, but decline the entire offer and don't launch any tasks.
2644 ACTION(DeclineOffers)
2645 {
2646  Call call;
2647  call.set_type(Call::DECLINE);
2648 
2649  Call::Decline* decline = call.mutable_decline();
2650 
2651  foreach (const Offer& offer, arg1.offers()) {
2652  decline->add_offer_ids()->CopyFrom(offer.id());
2653 
2654  if (!call.has_framework_id()) {
2655  call.mutable_framework_id()->CopyFrom(offer.framework_id());
2656  }
2657  }
2658 
2659  arg0->send(call);
2660 }
2661 
2662 
2663 ACTION_P(SendSubscribe, frameworkInfo)
2664 {
2665  Call call;
2666  call.set_type(Call::SUBSCRIBE);
2667  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2668 
2669  arg0->send(call);
2670 }
2671 
2672 
2673 ACTION_P2(SendSubscribe, frameworkInfo, frameworkId)
2674 {
2675  Call call;
2676  call.set_type(Call::SUBSCRIBE);
2677  call.mutable_framework_id()->CopyFrom(frameworkId);
2678  call.mutable_subscribe()->mutable_framework_info()->CopyFrom(frameworkInfo);
2679  call.mutable_subscribe()->mutable_framework_info()->mutable_id()->CopyFrom(
2680  frameworkId);
2681 
2682  arg0->send(call);
2683 }
2684 
2685 
2686 ACTION_P2(SendAcknowledge, frameworkId, agentId)
2687 {
2688  Call call;
2689  call.set_type(Call::ACKNOWLEDGE);
2690  call.mutable_framework_id()->CopyFrom(frameworkId);
2691 
2692  Call::Acknowledge* acknowledge = call.mutable_acknowledge();
2693  acknowledge->mutable_task_id()->CopyFrom(arg1.status().task_id());
2694  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2695  acknowledge->set_uuid(arg1.status().uuid());
2696 
2697  arg0->send(call);
2698 }
2699 
2700 
2702  SendAcknowledgeOperationStatus, frameworkId, agentId, resourceProviderId)
2703 {
2704  Call call;
2705  call.set_type(Call::ACKNOWLEDGE_OPERATION_STATUS);
2706  call.mutable_framework_id()->CopyFrom(frameworkId);
2707 
2708  Call::AcknowledgeOperationStatus* acknowledge =
2709  call.mutable_acknowledge_operation_status();
2710 
2711  acknowledge->mutable_agent_id()->CopyFrom(agentId);
2712  acknowledge->mutable_resource_provider_id()->CopyFrom(resourceProviderId);
2713  acknowledge->set_uuid(arg1.status().uuid().value());
2714  acknowledge->mutable_operation_id()->CopyFrom(arg1.status().operation_id());
2715 
2716  arg0->send(call);
2717 }
2718 
2719 } // namespace scheduler {
2720 
2724 
2725 } // namespace v1 {
2726 
2727 
2728 namespace executor {
2729 
2730 // A generic mock HTTP executor to be used in tests with gmock.
2731 template <typename Mesos, typename Event>
2733 {
2734 public:
2735  MOCK_METHOD1_T(connected, void(Mesos*));
2736  MOCK_METHOD1_T(disconnected, void(Mesos*));
2737  MOCK_METHOD2_T(subscribed, void(Mesos*, const typename Event::Subscribed&));
2738  MOCK_METHOD2_T(launch, void(Mesos*, const typename Event::Launch&));
2739  MOCK_METHOD2_T(launchGroup, void(Mesos*, const typename Event::LaunchGroup&));
2740  MOCK_METHOD2_T(kill, void(Mesos*, const typename Event::Kill&));
2741  MOCK_METHOD2_T(message, void(Mesos*, const typename Event::Message&));
2742  MOCK_METHOD1_T(shutdown, void(Mesos*));
2743  MOCK_METHOD2_T(error, void(Mesos*, const typename Event::Error&));
2744  MOCK_METHOD2_T(acknowledged,
2745  void(Mesos*, const typename Event::Acknowledged&));
2746 
2747  void events(Mesos* mesos, std::queue<Event> events)
2748  {
2749  while (!events.empty()) {
2750  Event event = std::move(events.front());
2751  events.pop();
2752 
2753  switch (event.type()) {
2754  case Event::SUBSCRIBED:
2755  subscribed(mesos, event.subscribed());
2756  break;
2757  case Event::LAUNCH:
2758  launch(mesos, event.launch());
2759  break;
2760  case Event::LAUNCH_GROUP:
2761  launchGroup(mesos, event.launch_group());
2762  break;
2763  case Event::KILL:
2764  kill(mesos, event.kill());
2765  break;
2766  case Event::ACKNOWLEDGED:
2767  acknowledged(mesos, event.acknowledged());
2768  break;
2769  case Event::MESSAGE:
2770  message(mesos, event.message());
2771  break;
2772  case Event::SHUTDOWN:
2773  shutdown(mesos);
2774  break;
2775  case Event::ERROR:
2776  error(mesos, event.error());
2777  break;
2778  case Event::UNKNOWN:
2779  LOG(FATAL) << "Received unexpected UNKNOWN event";
2780  break;
2781  }
2782  }
2783  }
2784 };
2785 
2786 
2787 // A generic testing interface for the executor library that can be used to
2788 // test the library across various versions.
2789 template <typename Mesos, typename Event>
2790 class TestMesos : public Mesos
2791 {
2792 public:
2794  ContentType contentType,
2795  const std::shared_ptr<MockHTTPExecutor<Mesos, Event>>& executor,
2796  const std::map<std::string, std::string>& environment)
2797  : Mesos(
2798  contentType,
2799  lambda::bind(&MockHTTPExecutor<Mesos, Event>::connected,
2800  executor,
2801  this),
2802  lambda::bind(&MockHTTPExecutor<Mesos, Event>::disconnected,
2803  executor,
2804  this),
2805  lambda::bind(&MockHTTPExecutor<Mesos, Event>::events,
2806  executor,
2807  this,
2808  lambda::_1),
2809  environment) {}
2810 };
2811 
2812 } // namespace executor {
2813 
2814 
2815 namespace v1 {
2816 namespace executor {
2817 
2818 // Alias existing `mesos::v1::executor` classes so that we can easily
2819 // write `v1::executor::` in tests.
2823 
2824 
2828 
2829 
2830 // TODO(anand): Move these actions to the `v1::executor` namespace.
2831 ACTION_P2(SendSubscribe, frameworkId, executorId)
2832 {
2834  call.mutable_framework_id()->CopyFrom(frameworkId);
2835  call.mutable_executor_id()->CopyFrom(executorId);
2836 
2837  call.set_type(mesos::v1::executor::Call::SUBSCRIBE);
2838 
2839  call.mutable_subscribe();
2840 
2841  arg0->send(call);
2842 }
2843 
2844 
2845 ACTION_P3(SendUpdateFromTask, frameworkId, executorId, state)
2846 {
2847  mesos::v1::TaskStatus status;
2848  status.mutable_task_id()->CopyFrom(arg1.task().task_id());
2849  status.mutable_executor_id()->CopyFrom(executorId);
2850  status.set_state(state);
2851  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
2852  status.set_uuid(id::UUID::random().toBytes());
2853 
2855  call.mutable_framework_id()->CopyFrom(frameworkId);
2856  call.mutable_executor_id()->CopyFrom(executorId);
2857 
2858  call.set_type(mesos::v1::executor::Call::UPDATE);
2859 
2860  call.mutable_update()->mutable_status()->CopyFrom(status);
2861 
2862  arg0->send(call);
2863 }
2864 
2865 
2866 ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
2867 {
2868  mesos::v1::TaskStatus status;
2869  status.mutable_task_id()->CopyFrom(arg1.task_id());
2870  status.mutable_executor_id()->CopyFrom(executorId);
2871  status.set_state(state);
2872  status.set_source(mesos::v1::TaskStatus::SOURCE_EXECUTOR);
2873  status.set_uuid(id::UUID::random().toBytes());
2874 
2876  call.mutable_framework_id()->CopyFrom(frameworkId);
2877  call.mutable_executor_id()->CopyFrom(executorId);
2878 
2879  call.set_type(mesos::v1::executor::Call::UPDATE);
2880 
2881  call.mutable_update()->mutable_status()->CopyFrom(status);
2882 
2883  arg0->send(call);
2884 }
2885 
2886 } // namespace executor {
2887 
2891 
2892 } // namespace v1 {
2893 
2894 
2895 namespace resource_provider {
2896 
2897 template <
2898  typename Event,
2899  typename Call,
2900  typename Driver,
2901  typename ResourceProviderInfo,
2902  typename Resource,
2903  typename Resources,
2904  typename ResourceProviderID,
2905  typename OperationState,
2906  typename Operation,
2907  typename Source>
2909 {
2910 public:
2912  const ResourceProviderInfo& _info,
2913  const Option<Resources>& _resources = None())
2914  : info(_info),
2915  resources(_resources)
2916  {
2917  ON_CALL(*this, connected())
2918  .WillByDefault(Invoke(
2919  this,
2921  Event,
2922  Call,
2923  Driver,
2924  ResourceProviderInfo,
2925  Resource,
2926  Resources,
2927  ResourceProviderID,
2928  OperationState,
2929  Operation,
2930  Source>::connectedDefault));
2931  EXPECT_CALL(*this, connected()).WillRepeatedly(DoDefault());
2932 
2933  ON_CALL(*this, subscribed(_))
2934  .WillByDefault(Invoke(
2935  this,
2937  Event,
2938  Call,
2939  Driver,
2940  ResourceProviderInfo,
2941  Resource,
2942  Resources,
2943  ResourceProviderID,
2944  OperationState,
2945  Operation,
2946  Source>::subscribedDefault));
2947  EXPECT_CALL(*this, subscribed(_)).WillRepeatedly(DoDefault());
2948 
2949  ON_CALL(*this, applyOperation(_))
2950  .WillByDefault(Invoke(
2951  this,
2953  Event,
2954  Call,
2955  Driver,
2956  ResourceProviderInfo,
2957  Resource,
2958  Resources,
2959  ResourceProviderID,
2960  OperationState,
2961  Operation,
2962  Source>::operationDefault));
2963  EXPECT_CALL(*this, applyOperation(_)).WillRepeatedly(DoDefault());
2964 
2965  ON_CALL(*this, publishResources(_))
2966  .WillByDefault(Invoke(
2967  this,
2969  Event,
2970  Call,
2971  Driver,
2972  ResourceProviderInfo,
2973  Resource,
2974  Resources,
2975  ResourceProviderID,
2976  OperationState,
2977  Operation,
2978  Source>::publishDefault));
2979  EXPECT_CALL(*this, publishResources(_)).WillRepeatedly(DoDefault());
2980 
2981  ON_CALL(*this, teardown())
2982  .WillByDefault(Invoke(
2983  this,
2985  Event,
2986  Call,
2987  Driver,
2988  ResourceProviderInfo,
2989  Resource,
2990  Resources,
2991  ResourceProviderID,
2992  OperationState,
2993  Operation,
2994  Source>::teardownDefault));
2995  EXPECT_CALL(*this, teardown()).WillRepeatedly(DoDefault());
2996  }
2997 
2998  MOCK_METHOD0_T(connected, void());
2999  MOCK_METHOD0_T(disconnected, void());
3000  MOCK_METHOD1_T(subscribed, void(const typename Event::Subscribed&));
3001  MOCK_METHOD1_T(applyOperation, void(const typename Event::ApplyOperation&));
3002  MOCK_METHOD1_T(
3003  publishResources,
3004  void(const typename Event::PublishResources&));
3005  MOCK_METHOD1_T(
3006  acknowledgeOperationStatus,
3007  void(const typename Event::AcknowledgeOperationStatus&));
3008  MOCK_METHOD1_T(
3009  reconcileOperations,
3010  void(const typename Event::ReconcileOperations&));
3011  MOCK_METHOD0_T(teardown, void());
3012 
3013  void events(std::queue<Event> events)
3014  {
3015  while (!events.empty()) {
3016  Event event = events.front();
3017  events.pop();
3018 
3019  switch (event.type()) {
3020  case Event::SUBSCRIBED:
3021  subscribed(event.subscribed());
3022  break;
3023  case Event::APPLY_OPERATION:
3024  applyOperation(event.apply_operation());
3025  break;
3026  case Event::PUBLISH_RESOURCES:
3027  publishResources(event.publish_resources());
3028  break;
3029  case Event::ACKNOWLEDGE_OPERATION_STATUS:
3030  acknowledgeOperationStatus(event.acknowledge_operation_status());
3031  break;
3032  case Event::RECONCILE_OPERATIONS:
3033  reconcileOperations(event.reconcile_operations());
3034  break;
3035  case Event::TEARDOWN:
3036  teardown();
3037  break;
3038  case Event::UNKNOWN:
3039  LOG(FATAL) << "Received unexpected UNKNOWN event";
3040  break;
3041  }
3042  }
3043  }
3044 
3045  process::Future<Nothing> send(const Call& call)
3046  {
3047  return driver->send(call);
3048  }
3049 
3050  void start(
3052  ContentType contentType)
3053  {
3054  Option<std::string> token;
3055 
3056 #ifdef USE_SSL_SOCKET
3058  DEFAULT_JWT_SECRET_KEY);
3059 
3060  // For resource provider authentication the chosen claims don't matter,
3061  // only the signature has to be valid.
3062  // TODO(nfnt): Revisit this once there's authorization of resource provider
3063  // API calls.
3065  claims["foo"] = "bar";
3066 
3067  process::http::authentication::Principal principal(None(), claims);
3068 
3069  process::Future<Secret> secret = secretGenerator.generate(principal);
3070 
3071  AWAIT_READY(secret);
3072 
3073  token = secret->value().data();
3074 #endif // USE_SSL_SOCKET
3075 
3076  driver.reset(new Driver(
3077  std::move(detector),
3078  contentType,
3079  lambda::bind(
3081  Event,
3082  Call,
3083  Driver,
3084  ResourceProviderInfo,
3085  Resource,
3086  Resources,
3087  ResourceProviderID,
3088  OperationState,
3089  Operation,
3090  Source>::connected,
3091  this),
3092  lambda::bind(
3094  Event,
3095  Call,
3096  Driver,
3097  ResourceProviderInfo,
3098  Resource,
3099  Resources,
3100  ResourceProviderID,
3101  OperationState,
3102  Operation,
3103  Source>::disconnected,
3104  this),
3105  lambda::bind(
3107  Event,
3108  Call,
3109  Driver,
3110  ResourceProviderInfo,
3111  Resource,
3112  Resources,
3113  ResourceProviderID,
3114  OperationState,
3115  Operation,
3116  Source>::events,
3117  this,
3118  lambda::_1),
3119  token));
3120 
3121  driver->start();
3122  }
3123 
3125  {
3126  Call call;
3127  call.set_type(Call::SUBSCRIBE);
3128  call.mutable_subscribe()->mutable_resource_provider_info()->CopyFrom(info);
3129 
3130  driver->send(call);
3131  }
3132 
3133  void subscribedDefault(const typename Event::Subscribed& subscribed)
3134  {
3135  info.mutable_id()->CopyFrom(subscribed.provider_id());
3136 
3137  if (resources.isSome()) {
3138  Resources injected;
3139 
3140  foreach (Resource resource, resources.get()) {
3141  resource.mutable_provider_id()->CopyFrom(info.id());
3142  injected += resource;
3143  }
3144 
3145  Call call;
3146  call.set_type(Call::UPDATE_STATE);
3147  call.mutable_resource_provider_id()->CopyFrom(info.id());
3148 
3149  typename Call::UpdateState* update = call.mutable_update_state();
3150  update->mutable_resources()->CopyFrom(injected);
3151  update->mutable_resource_version_uuid()->set_value(
3152  id::UUID::random().toBytes());
3153 
3154  driver->send(call);
3155  }
3156  }
3157 
3158  void operationDefault(const typename Event::ApplyOperation& operation)
3159  {
3160  CHECK(info.has_id());
3161 
3162  Call call;
3163  call.set_type(Call::UPDATE_OPERATION_STATUS);
3164  call.mutable_resource_provider_id()->CopyFrom(info.id());
3165 
3166  typename Call::UpdateOperationStatus* update =
3167  call.mutable_update_operation_status();
3168  update->mutable_framework_id()->CopyFrom(operation.framework_id());
3169  update->mutable_operation_uuid()->CopyFrom(operation.operation_uuid());
3170 
3171  update->mutable_status()->set_state(
3172  OperationState::OPERATION_FINISHED);
3173 
3174  switch (operation.info().type()) {
3175  case Operation::LAUNCH:
3177  break;
3178  case Operation::RESERVE:
3179  break;
3180  case Operation::UNRESERVE:
3181  break;
3182  case Operation::CREATE:
3183  break;
3184  case Operation::DESTROY:
3185  break;
3186  // TODO(zhitao): Implement default operation for `GROW_VOLUME` and
3187  // `SHRINK_VOLUME` on mocked resource provider.
3189  break;
3191  break;
3193  update->mutable_status()->add_converted_resources()->CopyFrom(
3194  operation.info().create_disk().source());
3195  update->mutable_status()
3196  ->mutable_converted_resources()
3197  ->Mutable(0)
3198  ->mutable_disk()
3199  ->mutable_source()
3200  ->set_type(operation.info().create_disk().target_type());
3201  break;
3203  update->mutable_status()->add_converted_resources()->CopyFrom(
3204  operation.info().destroy_disk().source());
3205  update->mutable_status()
3206  ->mutable_converted_resources()
3207  ->Mutable(0)
3208  ->mutable_disk()
3209  ->mutable_source()
3210  ->set_type(Source::RAW);
3211  break;
3212  case Operation::UNKNOWN:
3213  break;
3214  }
3215 
3216  update->mutable_latest_status()->CopyFrom(update->status());
3217 
3218  driver->send(call);
3219  }
3220 
3221  void publishDefault(const typename Event::PublishResources& publish)
3222  {
3223  CHECK(info.has_id());
3224 
3225  Call call;
3226  call.set_type(Call::UPDATE_PUBLISH_RESOURCES_STATUS);
3227  call.mutable_resource_provider_id()->CopyFrom(info.id());
3228 
3229  typename Call::UpdatePublishResourcesStatus* update =
3230  call.mutable_update_publish_resources_status();
3231  update->mutable_uuid()->CopyFrom(publish.uuid());
3232  update->set_status(Call::UpdatePublishResourcesStatus::OK);
3233 
3234  driver->send(call);
3235  }
3236 
3238 
3239  ResourceProviderInfo info;
3240 
3241 private:
3242  Option<Resources> resources;
3243  std::unique_ptr<Driver> driver;
3244 };
3245 
3247  const process::UPID& pid)
3248 {
3249  // Start and register a resource provider.
3250  std::string scheme = "http";
3251 
3252 #ifdef USE_SSL_SOCKET
3254  scheme = "https";
3255  }
3256 #endif
3257 
3258  process::http::URL url(
3259  scheme,
3260  pid.address.ip,
3261  pid.address.port,
3262  pid.id + "/api/v1/resource_provider");
3263 
3265 }
3266 
3267 } // namespace resource_provider {
3268 
3269 
3270 namespace v1 {
3271 namespace resource_provider {
3272 
3273 // Alias existing `mesos::v1::resource_provider` classes so that we can easily
3274 // write `v1::resource_provider::` in tests.
3277 
3278 } // namespace resource_provider {
3279 
3284  mesos::v1::ResourceProviderInfo,
3285  mesos::v1::Resource,
3287  mesos::v1::ResourceProviderID,
3288  mesos::v1::OperationState,
3290  mesos::v1::Resource::DiskInfo::Source>;
3291 
3292 } // namespace v1 {
3293 
3294 
3295 // Definition of a MockAuthorizer that can be used in tests with gmock.
3297 {
3298 public:
3299  MockAuthorizer();
3300  ~MockAuthorizer() override;
3301 
3302  MOCK_METHOD1(
3303  authorized, process::Future<bool>(const authorization::Request& request));
3304 
3305  MOCK_METHOD2(
3306  getObjectApprover, process::Future<process::Owned<ObjectApprover>>(
3307  const Option<authorization::Subject>& subject,
3308  const authorization::Action& action));
3309 };
3310 
3311 
3312 // Definition of a MockGarbageCollector that can be used in tests with gmock.
3314 {
3315 public:
3316  explicit MockGarbageCollector(const std::string& workDir);
3317  ~MockGarbageCollector() override;
3318 
3319  // The default action is to always return `true`.
3320  MOCK_METHOD1(unschedule, process::Future<bool>(const std::string& path));
3321 };
3322 
3323 
3325 {
3326 public:
3327  MockSecretGenerator() = default;
3328  ~MockSecretGenerator() override = default;
3329 
3330  MOCK_METHOD1(generate, process::Future<Secret>(
3331  const process::http::authentication::Principal& principal));
3332 };
3333 
3334 
3335 ACTION_P(SendStatusUpdateFromTask, state)
3336 {
3337  TaskStatus status;
3338  status.mutable_task_id()->MergeFrom(arg1.task_id());
3339  status.set_state(state);
3340  arg0->sendStatusUpdate(status);
3341 }
3342 
3343 
3344 ACTION_P(SendStatusUpdateFromTaskID, state)
3345 {
3346  TaskStatus status;
3347  status.mutable_task_id()->MergeFrom(arg1);
3348  status.set_state(state);
3349  arg0->sendStatusUpdate(status);
3350 }
3351 
3352 
3353 ACTION_P(SendFrameworkMessage, data)
3354 {
3355  arg0->sendFrameworkMessage(data);
3356 }
3357 
3358 
3359 #define FUTURE_PROTOBUF(message, from, to) \
3360  FutureProtobuf(message, from, to)
3361 
3362 
3363 #define DROP_PROTOBUF(message, from, to) \
3364  FutureProtobuf(message, from, to, true)
3365 
3366 
3367 #define DROP_PROTOBUFS(message, from, to) \
3368  DropProtobufs(message, from, to)
3369 
3370 
3371 #define EXPECT_NO_FUTURE_PROTOBUFS(message, from, to) \
3372  ExpectNoFutureProtobufs(message, from, to)
3373 
3374 
3375 #define FUTURE_HTTP_PROTOBUF(message, path, contentType) \
3376  FutureHttp(message, path, contentType)
3377 
3378 
3379 #define DROP_HTTP_PROTOBUF(message, path, contentType) \
3380  FutureHttp(message, path, contentType, true)
3381 
3382 
3383 #define DROP_HTTP_PROTOBUFS(message, path, contentType) \
3384  DropHttpProtobufs(message, path, contentType)
3385 
3386 
3387 #define EXPECT_NO_FUTURE_HTTP_PROTOBUFS(message, path, contentType) \
3388  ExpectNoFutureHttpProtobufs(message, path, contentType)
3389 
3390 
3391 // These are specialized versions of {FUTURE,DROP}_PROTOBUF that
3392 // capture a scheduler/executor Call protobuf of the given 'type'.
3393 // Note that we name methods as '*ProtobufUnion()' because these could
3394 // be reused for macros that capture any protobufs that are described
3395 // using the standard protocol buffer "union" trick (e.g.,
3396 // FUTURE_EVENT to capture scheduler::Event), see
3397 // https://developers.google.com/protocol-buffers/docs/techniques#union.
3398 
3399 #define FUTURE_CALL(message, unionType, from, to) \
3400  FutureUnionProtobuf(message, unionType, from, to)
3401 
3402 
3403 #define DROP_CALL(message, unionType, from, to) \
3404  FutureUnionProtobuf(message, unionType, from, to, true)
3405 
3406 
3407 #define DROP_CALLS(message, unionType, from, to) \
3408  DropUnionProtobufs(message, unionType, from, to)
3409 
3410 
3411 #define EXPECT_NO_FUTURE_CALLS(message, unionType, from, to) \
3412  ExpectNoFutureUnionProtobufs(message, unionType, from, to)
3413 
3414 
3415 #define FUTURE_CALL_MESSAGE(message, unionType, from, to) \
3416  process::FutureUnionMessage(message, unionType, from, to)
3417 
3418 
3419 #define DROP_CALL_MESSAGE(message, unionType, from, to) \
3420  process::FutureUnionMessage(message, unionType, from, to, true)
3421 
3422 
3423 #define FUTURE_HTTP_CALL(message, unionType, path, contentType) \
3424  FutureUnionHttp(message, unionType, path, contentType)
3425 
3426 
3427 #define DROP_HTTP_CALL(message, unionType, path, contentType) \
3428  FutureUnionHttp(message, unionType, path, contentType, true)
3429 
3430 
3431 #define DROP_HTTP_CALLS(message, unionType, path, contentType) \
3432  DropUnionHttpProtobufs(message, unionType, path, contentType)
3433 
3434 
3435 #define EXPECT_NO_FUTURE_HTTP_CALLS(message, unionType, path, contentType) \
3436  ExpectNoFutureUnionHttpProtobufs(message, unionType, path, contentType)
3437 
3438 
3439 // Forward declaration.
3440 template <typename T>
3441 T _FutureProtobuf(const process::Message& message);
3442 
3443 
3444 template <typename T, typename From, typename To>
3445 process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
3446 {
3447  // Help debugging by adding some "type constraints".
3448  { google::protobuf::Message* m = &t; (void) m; }
3449 
3450  return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
3451  .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
3452 }
3453 
3454 
3455 template <typename Message, typename UnionType, typename From, typename To>
3457  Message message, UnionType unionType, From from, To to, bool drop = false)
3458 {
3459  // Help debugging by adding some "type constraints".
3460  { google::protobuf::Message* m = &message; (void) m; }
3461 
3462  return process::FutureUnionMessage(message, unionType, from, to, drop)
3463  .then(lambda::bind(&_FutureProtobuf<Message>, lambda::_1));
3464 }
3465 
3466 
3467 template <typename Message, typename Path>
3469  Message message,
3470  Path path,
3471  ContentType contentType,
3472  bool drop = false)
3473 {
3474  // Help debugging by adding some "type constraints".
3475  { google::protobuf::Message* m = &message; (void) m; }
3476 
3477  auto deserializer =
3478  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3479 
3480  return process::FutureHttpRequest(message, path, deserializer, drop)
3481  .then([deserializer](const process::http::Request& request) {
3482  return deserializer(request.body).get();
3483  });
3484 }
3485 
3486 
3487 template <typename Message, typename UnionType, typename Path>
3489  Message message,
3490  UnionType unionType,
3491  Path path,
3492  ContentType contentType,
3493  bool drop = false)
3494 {
3495  // Help debugging by adding some "type constraints".
3496  { google::protobuf::Message* m = &message; (void) m; }
3497 
3498  auto deserializer =
3499  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3500 
3502  message, unionType, path, deserializer, drop)
3503  .then([deserializer](const process::http::Request& request) {
3504  return deserializer(request.body).get();
3505  });
3506 }
3507 
3508 
3509 template <typename T>
3511 {
3512  T t;
3513  t.ParseFromString(message.body);
3514  return t;
3515 }
3516 
3517 
3518 template <typename T, typename From, typename To>
3519 void DropProtobufs(T t, From from, To to)
3520 {
3521  // Help debugging by adding some "type constraints".
3522  { google::protobuf::Message* m = &t; (void) m; }
3523 
3524  process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
3525 }
3526 
3527 
3528 template <typename Message, typename UnionType, typename From, typename To>
3529 void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
3530 {
3531  // Help debugging by adding some "type constraints".
3532  { google::protobuf::Message* m = &message; (void) m; }
3533 
3534  process::DropUnionMessages(message, unionType, from, to);
3535 }
3536 
3537 
3538 template <typename Message, typename Path>
3540  Message message,
3541  Path path,
3542  ContentType contentType,
3543  bool drop = false)
3544 {
3545  // Help debugging by adding some "type constraints".
3546  { google::protobuf::Message* m = &message; (void) m; }
3547 
3548  auto deserializer =
3549  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3550 
3551  process::DropHttpRequests(message, path, deserializer);
3552 }
3553 
3554 
3555 template <typename Message, typename UnionType, typename Path>
3557  Message message,
3558  UnionType unionType,
3559  Path path,
3560  ContentType contentType,
3561  bool drop = false)
3562 {
3563  // Help debugging by adding some "type constraints".
3564  { google::protobuf::Message* m = &message; (void) m; }
3565 
3566  auto deserializer =
3567  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3568 
3569  process::DropUnionHttpRequests(message, unionType, path, deserializer);
3570 }
3571 
3572 
3573 template <typename T, typename From, typename To>
3574 void ExpectNoFutureProtobufs(T t, From from, To to)
3575 {
3576  // Help debugging by adding some "type constraints".
3577  { google::protobuf::Message* m = &t; (void) m; }
3578 
3579  process::ExpectNoFutureMessages(testing::Eq(t.GetTypeName()), from, to);
3580 }
3581 
3582 
3583 template <typename Message, typename UnionType, typename From, typename To>
3585  Message message, UnionType unionType, From from, To to)
3586 {
3587  // Help debugging by adding some "type constraints".
3588  { google::protobuf::Message* m = &message; (void) m; }
3589 
3590  process::ExpectNoFutureUnionMessages(message, unionType, from, to);
3591 }
3592 
3593 
3594 template <typename Message, typename Path>
3596  Message message,
3597  Path path,
3598  ContentType contentType,
3599  bool drop = false)
3600 {
3601  // Help debugging by adding some "type constraints".
3602  { google::protobuf::Message* m = &message; (void) m; }
3603 
3604  auto deserializer =
3605  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3606 
3607  process::ExpectNoFutureHttpRequests(message, path, deserializer);
3608 }
3609 
3610 
3611 template <typename Message, typename UnionType, typename Path>
3613  Message message,
3614  UnionType unionType,
3615  Path path,
3616  ContentType contentType,
3617  bool drop = false)
3618 {
3619  // Help debugging by adding some "type constraints".
3620  { google::protobuf::Message* m = &message; (void) m; }
3621 
3622  auto deserializer =
3623  lambda::bind(&deserialize<Message>, contentType, lambda::_1);
3624 
3626  message, unionType, path, deserializer);
3627 }
3628 
3629 
3630 // This matcher is used to match a vector of resource offers that
3631 // contains an offer having any resource that passes the filter.
3632 MATCHER_P(OffersHaveAnyResource, filter, "")
3633 {
3634  foreach (const Offer& offer, arg) {
3635  foreach (const Resource& resource, offer.resources()) {
3636  if (filter(resource)) {
3637  return true;
3638  }
3639  }
3640  }
3641 
3642  return false;
3643 }
3644 
3645 
3646 // This matcher is used to match a vector of resource offers that
3647 // contains an offer having the specified resource.
3648 MATCHER_P(OffersHaveResource, resource, "")
3649 {
3650  foreach (const Offer& offer, arg) {
3651  Resources resources = offer.resources();
3652 
3653  // If `resource` is not allocated, we are matching offers against
3654  // resources constructed from scratch, so we strip off allocations.
3655  if (!resource.has_allocation_info()) {
3656  resources.unallocate();
3657  }
3658 
3659  if (resources.contains(resource)) {
3660  return true;
3661  }
3662  }
3663 
3664  return false;
3665 }
3666 
3667 
3668 // This matcher is used to match the task id of a `TaskStatus` message.
3669 MATCHER_P(TaskStatusTaskIdEq, taskInfo, "")
3670 {
3671  return arg.task_id() == taskInfo.task_id();
3672 }
3673 
3674 
3675 // This matcher is used to match the state of a `TaskStatus` message.
3676 MATCHER_P(TaskStatusStateEq, taskState, "")
3677 {
3678  return arg.state() == taskState;
3679 }
3680 
3681 
3682 // This matcher is used to match the task id of an `Event.update.status`
3683 // message.
3684 MATCHER_P(TaskStatusUpdateTaskIdEq, taskInfo, "")
3685 {
3686  return arg.status().task_id() == taskInfo.task_id();
3687 }
3688 
3689 
3690 // This matcher is used to match the state of an `Event.update.status`
3691 // message.
3692 MATCHER_P(TaskStatusUpdateStateEq, taskState, "")
3693 {
3694  return arg.status().state() == taskState;
3695 }
3696 
3697 
3698 // This matcher is used to match the task id of
3699 // `authorization::Request.Object.TaskInfo`.
3700 MATCHER_P(AuthorizationRequestHasTaskID, taskId, "")
3701 {
3702  if (!arg.has_object()) {
3703  return false;
3704  }
3705 
3706  if (!arg.object().has_task_info()) {
3707  return false;
3708  }
3709 
3710  return arg.object().task_info().task_id() == taskId;
3711 }
3712 
3713 
3714 // This matcher is used to match the task id of `Option<TaskInfo>`.
3715 MATCHER_P(OptionTaskHasTaskID, taskId, "")
3716 {
3717  return arg.isNone() ? false : arg->task_id() == taskId;
3718 }
3719 
3720 
3721 // This matcher is used to match an `Option<TaskGroupInfo>` which contains a
3722 // task with the specified task id.
3723 MATCHER_P(OptionTaskGroupHasTaskID, taskId, "")
3724 {
3725  if (arg.isNone()) {
3726  return false;
3727  }
3728 
3729  foreach(const TaskInfo& taskInfo, arg->tasks()) {
3730  if (taskInfo.task_id() == taskId) {
3731  return true;
3732  }
3733  }
3734 
3735  return false;
3736 }
3737 
3738 
3740 {
3741 public:
3742  struct Printer
3743  {
3744  std::string operator()(
3745  const ::testing::TestParamInfo<ParamExecutorType>& info) const
3746  {
3747  switch (info.param.type) {
3748  case COMMAND:
3749  return "CommandExecutor";
3750  case DEFAULT:
3751  return "DefaultExecutor";
3752  default:
3753  UNREACHABLE();
3754  }
3755  }
3756  };
3757 
3759  {
3760  return ParamExecutorType(COMMAND);
3761  }
3762 
3764  {
3765  return ParamExecutorType(DEFAULT);
3766  }
3767 
3768  bool isCommandExecutor() const { return type == COMMAND; }
3769  bool isDefaultExecutor() const { return type == DEFAULT; }
3770 
3771 private:
3772  enum Type
3773  {
3774  COMMAND,
3775  DEFAULT
3776  };
3777 
3778  ParamExecutorType(Type _type) : type(_type) {}
3779 
3780  Type type;
3781 };
3782 
3783 } // namespace tests {
3784 } // namespace internal {
3785 } // namespace mesos {
3786 
3787 #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:1980
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:518
#define DEFAULT_FRAMEWORK_INFO
Definition: mesos.hpp:2274
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:1928
Try< bool > update(const std::string &link, const Handle &parent, uint16_t protocol, const action::Mirror &mirror)
DomainInfo createDomainInfo(Args &&...args)
Definition: mesos.hpp:1724
process::Owned< EndpointDetector > createEndpointDetector(const process::UPID &pid)
Definition: mesos.hpp:3246
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:1814
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
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:1917
mesos::v1::scheduler::Call createCallSubscribe(const mesos::v1::FrameworkInfo &frameworkInfo, const Option< mesos::v1::FrameworkID > &frameworkId=None())
Definition: mesos.hpp:2234
void events(std::queue< Event > events)
Definition: mesos.hpp:3013
void DropHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3539
mesos::v1::TaskInfo createTask(Args &&...args)
Definition: mesos.hpp:1887
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:2821
mesos::v1::resource_provider::Event Event
Definition: mesos.hpp:3276
void ExpectNoFutureUnionMessages(Message message, UnionType unionType, From from, To to)
Definition: gmock.hpp:675
Definition: message.hpp:22
void setAgentID(mesos::v1::TaskInfo *task, const mesos::v1::AgentID &agentId)
Definition: mesos.hpp:807
Result< std::string > user(Option< uid_t > uid=None())
Definition: su.hpp:284
Result< ProcessStatus > status(pid_t pid)
Definition: proc.hpp:166
mesos::v1::NetworkInfo createNetworkInfo(Args &&...args)
Definition: mesos.hpp:1868
const std::string defaultTaskResourcesString
Definition: mesos.hpp:295
Definition: uuid.hpp:33
mesos::v1::Volume createVolumeHostPath(Args &&...args)
Definition: mesos.hpp:1851
mesos::v1::Offer::Operation SHRINK_VOLUME(Args &&...args)
Definition: mesos.hpp:2065
virtual Status launchTasks(const std::vector< OfferID > &offerIds, const std::vector< TaskInfo > &tasks, const Filters &filters=Filters())=0
mesos::v1::Offer::Operation CREATE_DISK(Args &&...args)
Definition: mesos.hpp:2091
mesos::v1::scheduler::Call Call
Definition: mesos.hpp:2616
Definition: resources.hpp:81
mesos::v1::Offer::Operation RESERVE(Args &&...args)
Definition: mesos.hpp:2025
ResourceProviderInfo info
Definition: mesos.hpp:3239
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:3768
mesos::v1::ContainerInfo createContainerInfo(const Option< std::string > &imageName=None(), const std::vector< mesos::v1::Volume > &volumes={})
Definition: mesos.hpp:1876
Definition: lambda.hpp:30
void DropUnionHttpRequests(Message message, UnionType unionType, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:602
Definition: scheduler.hpp:70
Operation
Definition: cgroups.hpp:458
mesos::v1::Resource::DiskInfo::Source createDiskSourceMount(Args &&...args)
Definition: mesos.hpp:1953
Definition: flags.hpp:39
T _FutureProtobuf(const process::Message &message)
Definition: mesos.hpp:3510
mesos::v1::Offer::Operation DESTROY_DISK(Args &&...args)
Definition: mesos.hpp:2101
mesos::v1::CommandInfo createCommandInfo(const Option< std::string > &value=None(), const std::vector< std::string > &arguments={})
Definition: mesos.hpp:1826
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:1529
void DropUnionProtobufs(Message message, UnionType unionType, From from, To to)
Definition: mesos.hpp:3529
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:2163
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:2617
mesos::v1::Volume createVolumeSandboxPath(Args &&...args)
Definition: mesos.hpp:1843
static Try< Resource > parse(const std::string &name, const std::string &value, const std::string &role)
Returns a Resource with the given name, value, and role.
Resource provider driver.
Definition: resource_provider.hpp:56
void DropHttpRequests(Message message, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:581
mesos::v1::Resource::DiskInfo::Source createDiskSourcePath(Args &&...args)
Definition: mesos.hpp:1944
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector, const FrameworkInfo &framework, bool implicitAcknowledgements, const Credential &credential)
Definition: mesos.hpp:2461
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:3488
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:1971
mesos::v1::scheduler::APIResult APIResult
Definition: mesos.hpp:2615
Definition: scheduler.hpp:185
mesos::v1::TaskGroupInfo createTaskGroupInfo(const std::vector< mesos::v1::TaskInfo > &tasks)
Definition: mesos.hpp:1901
#define CHECK_SOME(expression)
Definition: check.hpp:50
mesos::v1::Resource::ReservationInfo createStaticReservationInfo(const std::string &role)
Definition: mesos.hpp:1910
Definition: containerizer.hpp:59
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:569
An "untyped" PID, used to encapsulate the process ID for lower-layer abstractions (eg...
Definition: pid.hpp:39
Definition: http.hpp:128
const ExecutorID id
Definition: mesos.hpp:2420
#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:2033
void events(Mesos *mesos, std::queue< Event > events)
Definition: mesos.hpp:2509
mesos::v1::Image createDockerImage(Args &&...args)
Definition: mesos.hpp:1835
Result< std::vector< Filter< Classifier > > > filters(const std::string &_link, const Handle &parent)
Definition: internal.hpp:769
mesos::v1::Volume createVolumeFromDockerImage(Args &&...args)
Definition: mesos.hpp:1860
#define DEFAULT_CREDENTIAL
Definition: mesos.hpp:2270
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:3584
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:26
constexpr char READONLY_HTTP_AUTHENTICATION_REALM[]
Definition: mesos.hpp:108
mesos::v1::Offer::Operation DESTROY(Args &&...args)
Definition: mesos.hpp:2049
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:3744
Resources toUnreserved() const
Try< ImageManifest > parse(const std::string &value)
Definition: parse.hpp:36
void DropProtobufs(T t, From from, To to)
Definition: mesos.hpp:3519
mesos::v1::scheduler::Call createCallReconcileOperations(const mesos::v1::FrameworkID &frameworkId, const std::vector< mesos::v1::scheduler::Call::ReconcileOperations::Operation > &operations={})
Definition: mesos.hpp:2210
const T & get() const &
Definition: option.hpp:118
process::http::Headers createBasicAuthHeaders(Args &&...args)
Definition: mesos.hpp:2000
Definition: resources.hpp:81
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:3763
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:3468
mesos::v1::Parameters parameterize(Args &&...args)
Definition: mesos.hpp:2109
Definition: executor.hpp:55
mesos::v1::resource_provider::Call Call
Definition: mesos.hpp:3275
bool isDefaultExecutor() const
Definition: mesos.hpp:3769
mesos::v1::Resource::DiskInfo::Source createDiskSourceBlock(Args &&...args)
Definition: mesos.hpp:1962
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:2564
JSON::Proxy jsonify(const T &)
Definition: jsonify.hpp:701
#define UNREACHABLE()
Definition: unreachable.hpp:22
static ParamExecutorType commandExecutor()
Definition: mesos.hpp:3758
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:2820
Future< Message > FutureMessage(Name name, From from, To to, bool drop=false)
Definition: gmock.hpp:499
void events(Mesos *mesos, std::queue< Event > events)
Definition: mesos.hpp:2747
void operationDefault(const typename Event::ApplyOperation &operation)
Definition: mesos.hpp:3158
void ExpectNoFutureUnionHttpRequests(Message message, UnionType unionType, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:643
Iterable< V > map(F &&f, const Iterable< U, Us... > &input)
Definition: lambda.hpp:46
Definition: protobuf.hpp: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:3456
void start(process::Owned< mesos::internal::EndpointDetector > detector, ContentType contentType)
Definition: mesos.hpp:3050
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:3045
void ExpectNoFutureMessages(Name name, From from, To to)
Definition: gmock.hpp:663
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector, const FrameworkInfo &framework, bool implicitAcknowledgements=true)
Definition: mesos.hpp:2443
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:3612
void ExpectNoFutureHttpProtobufs(Message message, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3595
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:2185
mesos::v1::Offer::Operation CREATE(Args &&...args)
Definition: mesos.hpp:2041
void SetUp() override
Definition: utils.hpp:36
MockResourceProvider(const ResourceProviderInfo &_info, const Option< Resources > &_resources=None())
Definition: mesos.hpp:2911
std::string body
Definition: http.hpp:562
uint64_t bytes() const
Definition: bytes.hpp:79
Definition: mesos.hpp:3296
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:3221
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:473
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:2793
ACTION_P3(SendUpdateFromTaskID, frameworkId, executorId, state)
Definition: mesos.hpp:2866
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:2313
static TCredential create()
Definition: mesos.hpp:495
void allocate(const std::string &role)
void ExpectNoFutureProtobufs(T t, From from, To to)
Definition: mesos.hpp:3574
process::Future< T > FutureProtobuf(T t, From from, To to, bool drop=false)
Definition: mesos.hpp:3445
hashmap< std::string, double > convertToHashmap(Args &&...args)
Definition: mesos.hpp:2017
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:2402
Try< Nothing > kill(const std::string &hierarchy, const std::string &cgroup, int signal)
void subscribedDefault(const typename Event::Subscribed &subscribed)
Definition: mesos.hpp:3133
mesos::v1::Offer::Operation LAUNCH(const std::vector< mesos::v1::TaskInfo > &tasks)
Definition: mesos.hpp:2073
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:1990
Definition: qos_controller.hpp:44
mesos::v1::scheduler::Call createCallAccept(const mesos::v1::FrameworkID &frameworkId, const mesos::v1::Offer &offer, const std::vector< mesos::v1::Offer::Operation > &operations, const Option< mesos::v1::Filters > &filters=None())
Definition: mesos.hpp:2116
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:2009
mesos::v1::scheduler::Response Response
Definition: mesos.hpp:2619
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)
void TearDown() override
Definition: utils.hpp:62
net::IP ip
Definition: address.hpp:133
~TestMesos() override
Definition: mesos.hpp:2586
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:2081
TestingMesosSchedulerDriver(Scheduler *scheduler, mesos::master::detector::MasterDetector *_detector)
Definition: mesos.hpp:2427
mesos::v1::Offer::Operation GROW_VOLUME(Args &&...args)
Definition: mesos.hpp:2057
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:622
ACTION(DeclineOffers)
Definition: mesos.hpp:2364
Future< http::Request > FutureHttpRequest(Message message, Path path, Deserializer deserializer, bool drop=false)
Definition: gmock.hpp:445
constexpr const char * name
Definition: shell.hpp:43
void DropUnionHttpProtobufs(Message message, UnionType unionType, Path path, ContentType contentType, bool drop=false)
Definition: mesos.hpp:3556
mesos::v1::Resource::DiskInfo createDiskInfo(Args &&...args)
Definition: mesos.hpp:1936
mesos::v1::executor::Mesos Mesos
Definition: mesos.hpp:2822
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:2141
Try< std::set< std::string > > subsystems()
Definition: mesos.hpp:2281
void filter(Filter *filter)
virtual master::Flags CreateMasterFlags()
MATCHER_P(OffersHaveAnyResource, filter,"")
Definition: mesos.hpp:3632
TOffer::Operation CREATE_DISK(const TResource &source, const TTargetType &type, const Option< std::string > &operationId=None())
Definition: mesos.hpp:1402
void DropMessages(Name name, From from, To to)
Definition: gmock.hpp:557
mesos::Environment createEnvironment(const hashmap< std::string, std::string > &map)
Definition: mesos.hpp:2253