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