Apache Mesos
allocator.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_ALLOCATOR_HPP__
18 #define __TESTS_ALLOCATOR_HPP__
19 
20 #include <gmock/gmock.h>
21 
23 
24 #include <process/future.hpp>
25 #include <process/gmock.hpp>
26 #include <process/owned.hpp>
27 
29 
30 using ::testing::_;
31 using ::testing::An;
32 using ::testing::DoDefault;
33 using ::testing::Invoke;
34 using ::testing::Return;
35 
37 
38 namespace mesos {
39 namespace internal {
40 namespace tests {
41 
42 // Allocator test helpers.
43 
44 Quota createQuota(const std::string& guarantees, const std::string& limits);
45 
46 
47 // This is a legacy helper where we take in a resource string
48 // and use that to set both quota guarantees and limits.
49 Quota createQuota(const std::string& resources);
50 
51 
52 WeightInfo createWeightInfo(const std::string& role, double weight);
53 
54 
55 // The following actions make up for the fact that DoDefault
56 // cannot be used inside a DoAll, for example:
57 // EXPECT_CALL(allocator, addFramework(_, _, _, _, _))
58 // .WillOnce(DoAll(InvokeAddFramework(&allocator),
59 // FutureSatisfy(&addFramework)));
60 
61 ACTION_P(InvokeInitialize, allocator)
62 {
63  allocator->real->initialize(arg0, arg1, arg2);
64 }
65 
66 
67 ACTION_P(InvokeRecover, allocator)
68 {
69  allocator->real->recover(arg0, arg1);
70 }
71 
72 
73 ACTION_P(InvokeAddFramework, allocator)
74 {
75  allocator->real->addFramework(arg0, arg1, arg2, arg3, arg4);
76 }
77 
78 
79 ACTION_P(InvokeRemoveFramework, allocator)
80 {
81  allocator->real->removeFramework(arg0);
82 }
83 
84 
85 ACTION_P(InvokeActivateFramework, allocator)
86 {
87  allocator->real->activateFramework(arg0);
88 }
89 
90 
91 ACTION_P(InvokeDeactivateFramework, allocator)
92 {
93  allocator->real->deactivateFramework(arg0);
94 }
95 
96 
97 ACTION_P(InvokeUpdateFramework, allocator)
98 {
99  allocator->real->updateFramework(arg0, arg1, arg2);
100 }
101 
102 
103 ACTION_P(InvokeAddSlave, allocator)
104 {
105  allocator->real->addSlave(arg0, arg1, arg2, arg3, arg4, arg5);
106 }
107 
108 
109 ACTION_P(InvokeRemoveSlave, allocator)
110 {
111  allocator->real->removeSlave(arg0);
112 }
113 
114 
115 ACTION_P(InvokeUpdateSlave, allocator)
116 {
117  allocator->real->updateSlave(arg0, arg1, arg2, arg3);
118 }
119 
120 
121 ACTION_P(InvokeAddResourceProvider, allocator)
122 {
123  allocator->real->addResourceProvider(arg0, arg1, arg2);
124 }
125 
126 
127 ACTION_P(InvokeActivateSlave, allocator)
128 {
129  allocator->real->activateSlave(arg0);
130 }
131 
132 
133 ACTION_P(InvokeDeactivateSlave, allocator)
134 {
135  allocator->real->deactivateSlave(arg0);
136 }
137 
138 
139 ACTION_P(InvokeUpdateWhitelist, allocator)
140 {
141  allocator->real->updateWhitelist(arg0);
142 }
143 
144 
145 ACTION_P(InvokeRequestResources, allocator)
146 {
147  allocator->real->requestResources(arg0, arg1);
148 }
149 
150 
151 ACTION_P(InvokeUpdateAllocation, allocator)
152 {
153  allocator->real->updateAllocation(arg0, arg1, arg2, arg3);
154 }
155 
156 
157 ACTION_P(InvokeUpdateAvailable, allocator)
158 {
159  return allocator->real->updateAvailable(arg0, arg1);
160 }
161 
162 
163 ACTION_P(InvokeUpdateUnavailability, allocator)
164 {
165  return allocator->real->updateUnavailability(arg0, arg1);
166 }
167 
168 
169 ACTION_P(InvokeUpdateInverseOffer, allocator)
170 {
171  return allocator->real->updateInverseOffer(arg0, arg1, arg2, arg3, arg4);
172 }
173 
174 
175 ACTION_P(InvokeGetInverseOfferStatuses, allocator)
176 {
177  return allocator->real->getInverseOfferStatuses();
178 }
179 
180 
181 ACTION_P(InvokeTransitionOfferedToAllocated, allocator)
182 {
183  allocator->real->transitionOfferedToAllocated(arg0, arg1);
184 }
185 
186 
187 ACTION_P(InvokeRecoverResources, allocator)
188 {
189  allocator->real->recoverResources(arg0, arg1, arg2, arg3, arg4);
190 }
191 
192 
193 ACTION_P2(InvokeRecoverResourcesWithFilters, allocator, timeout)
194 {
195  Filters filters;
196  filters.set_refuse_seconds(timeout);
197 
198  allocator->real->recoverResources(arg0, arg1, arg2, filters, false);
199 }
200 
201 
202 ACTION_P(InvokeSuppressOffers, allocator)
203 {
204  allocator->real->suppressOffers(arg0, arg1);
205 }
206 
207 
208 ACTION_P(InvokeReviveOffers, allocator)
209 {
210  allocator->real->reviveOffers(arg0, arg1);
211 }
212 
213 
214 ACTION_P(InvokeUpdateQuota, allocator)
215 {
216  allocator->real->updateQuota(arg0, arg1);
217 }
218 
219 
220 ACTION_P(InvokeUpdateWeights, allocator)
221 {
222  allocator->real->updateWeights(arg0);
223 }
224 
225 
226 ACTION_P(InvokePause, allocator)
227 {
228  allocator->real->pause();
229 }
230 
231 
232 ACTION_P(InvokeResume, allocator)
233 {
234  allocator->real->resume();
235 }
236 
237 
238 template <typename T = master::allocator::HierarchicalDRFAllocator>
240 {
241  // T represents the allocator type. It can be a default built-in
242  // allocator, or one provided by an allocator module.
244  CHECK_SOME(instance);
245  return CHECK_NOTNULL(instance.get());
246 }
247 
248 template <typename T = master::allocator::HierarchicalDRFAllocator>
250 {
251 public:
252  // Actual allocation is done by an instance of real allocator,
253  // which is specified by the template parameter.
255  {
256  // We use 'ON_CALL' and 'WillByDefault' here to specify the
257  // default actions (call in to the real allocator). This allows
258  // the tests to leverage the 'DoDefault' action.
259  // However, 'ON_CALL' results in a "Uninteresting mock function
260  // call" warning unless each test puts expectations in place.
261  // As a result, we also use 'EXPECT_CALL' and 'WillRepeatedly'
262  // to get the best of both worlds: the ability to use 'DoDefault'
263  // and no warnings when expectations are not explicit.
264 
265  ON_CALL(*this, initialize(_, _, _))
266  .WillByDefault(InvokeInitialize(this));
267  EXPECT_CALL(*this, initialize(_, _, _))
268  .WillRepeatedly(DoDefault());
269 
270  ON_CALL(*this, recover(_, _))
271  .WillByDefault(InvokeRecover(this));
272  EXPECT_CALL(*this, recover(_, _))
273  .WillRepeatedly(DoDefault());
274 
275  ON_CALL(*this, addFramework(_, _, _, _, _))
276  .WillByDefault(InvokeAddFramework(this));
277  EXPECT_CALL(*this, addFramework(_, _, _, _, _))
278  .WillRepeatedly(DoDefault());
279 
280  ON_CALL(*this, removeFramework(_))
281  .WillByDefault(InvokeRemoveFramework(this));
282  EXPECT_CALL(*this, removeFramework(_))
283  .WillRepeatedly(DoDefault());
284 
285  ON_CALL(*this, activateFramework(_))
286  .WillByDefault(InvokeActivateFramework(this));
287  EXPECT_CALL(*this, activateFramework(_))
288  .WillRepeatedly(DoDefault());
289 
290  ON_CALL(*this, deactivateFramework(_))
291  .WillByDefault(InvokeDeactivateFramework(this));
292  EXPECT_CALL(*this, deactivateFramework(_))
293  .WillRepeatedly(DoDefault());
294 
295  ON_CALL(*this, updateFramework(_, _, _))
296  .WillByDefault(InvokeUpdateFramework(this));
297  EXPECT_CALL(*this, updateFramework(_, _, _))
298  .WillRepeatedly(DoDefault());
299 
300  ON_CALL(*this, addSlave(_, _, _, _, _, _))
301  .WillByDefault(InvokeAddSlave(this));
302  EXPECT_CALL(*this, addSlave(_, _, _, _, _, _))
303  .WillRepeatedly(DoDefault());
304 
305  ON_CALL(*this, removeSlave(_))
306  .WillByDefault(InvokeRemoveSlave(this));
307  EXPECT_CALL(*this, removeSlave(_))
308  .WillRepeatedly(DoDefault());
309 
310  ON_CALL(*this, updateSlave(_, _, _, _))
311  .WillByDefault(InvokeUpdateSlave(this));
312  EXPECT_CALL(*this, updateSlave(_, _, _, _))
313  .WillRepeatedly(DoDefault());
314 
315  ON_CALL(*this, addResourceProvider(_, _, _))
316  .WillByDefault(InvokeAddResourceProvider(this));
317  EXPECT_CALL(*this, addResourceProvider(_, _, _))
318  .WillRepeatedly(DoDefault());
319 
320  ON_CALL(*this, activateSlave(_))
321  .WillByDefault(InvokeActivateSlave(this));
322  EXPECT_CALL(*this, activateSlave(_))
323  .WillRepeatedly(DoDefault());
324 
325  ON_CALL(*this, deactivateSlave(_))
326  .WillByDefault(InvokeDeactivateSlave(this));
327  EXPECT_CALL(*this, deactivateSlave(_))
328  .WillRepeatedly(DoDefault());
329 
330  ON_CALL(*this, updateWhitelist(_))
331  .WillByDefault(InvokeUpdateWhitelist(this));
332  EXPECT_CALL(*this, updateWhitelist(_))
333  .WillRepeatedly(DoDefault());
334 
335  ON_CALL(*this, requestResources(_, _))
336  .WillByDefault(InvokeRequestResources(this));
337  EXPECT_CALL(*this, requestResources(_, _))
338  .WillRepeatedly(DoDefault());
339 
340  ON_CALL(*this, updateAllocation(_, _, _, _))
341  .WillByDefault(InvokeUpdateAllocation(this));
342  EXPECT_CALL(*this, updateAllocation(_, _, _, _))
343  .WillRepeatedly(DoDefault());
344 
345  ON_CALL(*this, updateAvailable(_, _))
346  .WillByDefault(InvokeUpdateAvailable(this));
347  EXPECT_CALL(*this, updateAvailable(_, _))
348  .WillRepeatedly(DoDefault());
349 
350  ON_CALL(*this, updateUnavailability(_, _))
351  .WillByDefault(InvokeUpdateUnavailability(this));
352  EXPECT_CALL(*this, updateUnavailability(_, _))
353  .WillRepeatedly(DoDefault());
354 
355  ON_CALL(*this, updateInverseOffer(_, _, _, _, _))
356  .WillByDefault(InvokeUpdateInverseOffer(this));
357  EXPECT_CALL(*this, updateInverseOffer(_, _, _, _, _))
358  .WillRepeatedly(DoDefault());
359 
360  ON_CALL(*this, getInverseOfferStatuses())
361  .WillByDefault(InvokeGetInverseOfferStatuses(this));
362  EXPECT_CALL(*this, getInverseOfferStatuses())
363  .WillRepeatedly(DoDefault());
364 
365  ON_CALL(*this, transitionOfferedToAllocated(_, _))
366  .WillByDefault(InvokeTransitionOfferedToAllocated(this));
367  EXPECT_CALL(*this, transitionOfferedToAllocated(_, _))
368  .WillRepeatedly(DoDefault());
369 
370  ON_CALL(*this, recoverResources(_, _, _, _, _))
371  .WillByDefault(InvokeRecoverResources(this));
372  EXPECT_CALL(*this, recoverResources(_, _, _, _, _))
373  .WillRepeatedly(DoDefault());
374 
375  ON_CALL(*this, suppressOffers(_, _))
376  .WillByDefault(InvokeSuppressOffers(this));
377  EXPECT_CALL(*this, suppressOffers(_, _))
378  .WillRepeatedly(DoDefault());
379 
380  ON_CALL(*this, reviveOffers(_, _))
381  .WillByDefault(InvokeReviveOffers(this));
382  EXPECT_CALL(*this, reviveOffers(_, _))
383  .WillRepeatedly(DoDefault());
384 
385  ON_CALL(*this, updateQuota(_, _))
386  .WillByDefault(InvokeUpdateQuota(this));
387  EXPECT_CALL(*this, updateQuota(_, _))
388  .WillRepeatedly(DoDefault());
389 
390  ON_CALL(*this, updateWeights(_))
391  .WillByDefault(InvokeUpdateWeights(this));
392  EXPECT_CALL(*this, updateWeights(_))
393  .WillRepeatedly(DoDefault());
394 
395  ON_CALL(*this, pause())
396  .WillByDefault(InvokePause(this));
397  EXPECT_CALL(*this, pause())
398  .WillRepeatedly(DoDefault());
399 
400  ON_CALL(*this, resume())
401  .WillByDefault(InvokeResume(this));
402  EXPECT_CALL(*this, resume())
403  .WillRepeatedly(DoDefault());
404  }
405 
406  ~TestAllocator() override {}
407 
408  MOCK_METHOD3(initialize, void(
409  const Options& options,
410  const lambda::function<
411  void(const FrameworkID&,
412  const hashmap<std::string, hashmap<SlaveID, Resources>>&)>&,
413  const lambda::function<
414  void(const FrameworkID&,
416 
417  MOCK_METHOD2(recover, void(
418  const int expectedAgentCount,
420 
422  const FrameworkID&,
423  const FrameworkInfo&,
425  bool active,
426  const std::set<std::string>&));
427 
429  const FrameworkID&));
430 
432  const FrameworkID&));
433 
435  const FrameworkID&));
436 
438  const FrameworkID&,
439  const FrameworkInfo&,
440  const std::set<std::string>&));
441 
442  MOCK_METHOD6(addSlave, void(
443  const SlaveID&,
444  const SlaveInfo&,
445  const std::vector<SlaveInfo::Capability>&,
446  const Option<Unavailability>&,
447  const Resources&,
449 
451  const SlaveID&));
452 
454  const SlaveID&,
455  const SlaveInfo&,
456  const Option<Resources>&,
457  const Option<std::vector<SlaveInfo::Capability>>&));
458 
460  const SlaveID&,
461  const Resources&,
463 
465  const SlaveID&));
466 
468  const SlaveID&));
469 
471  const Option<hashset<std::string>>&));
472 
474  const FrameworkID&,
475  const std::vector<Request>&));
476 
478  const FrameworkID&,
479  const SlaveID&,
480  const Resources&,
481  const std::vector<ResourceConversion>&));
482 
484  const SlaveID&,
485  const std::vector<Offer::Operation>&));
486 
488  const SlaveID&,
489  const Option<Unavailability>&));
490 
492  const SlaveID&,
493  const FrameworkID&,
496  const Option<Filters>&));
497 
499  hashmap<SlaveID, hashmap<
500  FrameworkID,
501  mesos::allocator::InverseOfferStatus>>>());
502 
504  const SlaveID&,
505  const Resources&));
506 
508  const FrameworkID&,
509  const SlaveID&,
510  const Resources&,
511  const Option<Filters>& filters,
512  bool isAllocated));
513 
515  const FrameworkID&,
516  const std::set<std::string>&));
517 
519  const FrameworkID&,
520  const std::set<std::string>&));
521 
523  const std::string&,
524  const Quota&));
525 
527  const std::vector<WeightInfo>&));
528 
529  MOCK_METHOD0(pause, void());
530 
531  MOCK_METHOD0(resume, void());
532 
534 };
535 
536 } // namespace tests {
537 } // namespace internal {
538 } // namespace mesos {
539 
540 #endif // __TESTS_ALLOCATOR_HPP__
MOCK_METHOD6(addSlave, void(const SlaveID &, const SlaveInfo &, const std::vector< SlaveInfo::Capability > &, const Option< Unavailability > &, const Resources &, const hashmap< FrameworkID, Resources > &))
virtual void addResourceProvider(const SlaveID &slave, const Resources &total, const hashmap< FrameworkID, Resources > &used)=0
Add resources from a local resource provider to an agent.
constexpr const char * arg1
Definition: shell.hpp:45
Definition: option.hpp:29
T & get()&
Definition: try.hpp:80
Definition: check.hpp:33
virtual void pause()=0
Idempotent helper to pause allocations.
virtual void activateSlave(const SlaveID &slaveId)=0
Activates an agent.
virtual void updateAllocation(const FrameworkID &frameworkId, const SlaveID &slaveId, const Resources &offeredResources, const std::vector< ResourceConversion > &conversions)=0
Updates allocation by applying offer operations.
TestAllocator()
Definition: allocator.hpp:254
Definition: resources.hpp:83
virtual void reviveOffers(const FrameworkID &frameworkId, const std::set< std::string > &roles)=0
Revives offers to this framework for the specified roles.
Pass in configuration to the allocator.
Definition: allocator.hpp:49
mesos::allocator::Allocator * createAllocator()
Definition: allocator.hpp:239
virtual process::Future< hashmap< SlaveID, hashmap< FrameworkID, mesos::allocator::InverseOfferStatus > > > getInverseOfferStatuses()=0
Retrieves the status of all inverse offers maintained by the allocator.
virtual void deactivateFramework(const FrameworkID &frameworkId)=0
Deactivates a framework in the Mesos cluster.
WeightInfo createWeightInfo(const std::string &role, double weight)
constexpr const char * arg0
Definition: shell.hpp:44
virtual void addFramework(const FrameworkID &frameworkId, const FrameworkInfo &frameworkInfo, const hashmap< SlaveID, Resources > &used, bool active, const std::set< std::string > &suppressedRoles)=0
Adds a framework to the Mesos cluster.
Definition: hashmap.hpp:38
virtual void initialize(const Options &options, const lambda::function< void(const FrameworkID &, const hashmap< std::string, hashmap< SlaveID, Resources >> &)> &offerCallback, const lambda::function< void(const FrameworkID &, const hashmap< SlaveID, UnavailableResources > &)> &inverseOfferCallback)=0
Initializes the allocator when the master starts up.
virtual void updateWeights(const std::vector< WeightInfo > &weightInfos)=0
Updates the weight associated with one or more roles.
virtual void updateQuota(const std::string &role, const Quota &quota)=0
Informs the allocator to update quota for the given role.
#define CHECK_SOME(expression)
Definition: check.hpp:50
virtual void removeSlave(const SlaveID &slaveId)=0
Removes an agent from the Mesos cluster.
virtual void activateFramework(const FrameworkID &frameworkId)=0
Activates a framework in the Mesos cluster.
Result< std::vector< Filter< Classifier > > > filters(const std::string &_link, const Handle &parent)
Definition: internal.hpp:769
virtual void updateFramework(const FrameworkID &frameworkId, const FrameworkInfo &frameworkInfo, const std::set< std::string > &suppressedRoles)=0
Updates capabilities of a framework in the Mesos cluster.
Definition: allocator.hpp:249
virtual void resume()=0
Idempotent helper to resume allocations.
MOCK_METHOD4(updateSlave, void(const SlaveID &, const SlaveInfo &, const Option< Resources > &, const Option< std::vector< SlaveInfo::Capability >> &))
Definition: agent.hpp:25
virtual void recoverResources(const FrameworkID &frameworkId, const SlaveID &slaveId, const Resources &resources, const Option< Filters > &filters, bool isAllocated)=0
Recovers resources.
virtual void removeFramework(const FrameworkID &frameworkId)=0
Removes a framework from the Mesos cluster.
MOCK_METHOD5(addFramework, void(const FrameworkID &, const FrameworkInfo &, const hashmap< SlaveID, Resources > &, bool active, const std::set< std::string > &))
virtual void updateUnavailability(const SlaveID &slaveId, const Option< Unavailability > &unavailability)=0
Updates unavailability for an agent.
virtual void addSlave(const SlaveID &slaveId, const SlaveInfo &slaveInfo, const std::vector< SlaveInfo::Capability > &capabilities, const Option< Unavailability > &unavailability, const Resources &total, const hashmap< FrameworkID, Resources > &used)=0
Adds or re-adds an agent to the Mesos cluster.
Basic model of an allocator: resources are allocated to a framework in the form of offers...
Definition: allocator.hpp:82
virtual void deactivateSlave(const SlaveID &slaveId)=0
Deactivates an agent.
Definition: attributes.hpp:24
virtual void transitionOfferedToAllocated(const SlaveID &slaveId, const Resources &resources)=0
This method should be invoked when the offered resources has become actually allocated.
~TestAllocator() override
Definition: allocator.hpp:406
virtual void updateWhitelist(const Option< hashset< std::string >> &whitelist)=0
Updates the list of trusted agents.
process::Owned< mesos::allocator::Allocator > real
Definition: allocator.hpp:533
virtual void requestResources(const FrameworkID &frameworkId, const std::vector< Request > &requests)=0
Requests resources for a framework.
Try< Nothing > create(const std::string &hierarchy, const std::string &cgroup, bool recursive=false)
ACTION_P2(InvokeRecoverResourcesWithFilters, allocator, timeout)
Definition: allocator.hpp:193
virtual void recover(const int expectedAgentCount, const hashmap< std::string, Quota > &quotas)=0
Informs the allocator of the recovered state from the master.
ACTION_P(InvokeInitialize, allocator)
Definition: allocator.hpp:61
MOCK_METHOD2(recover, void(const int expectedAgentCount, const hashmap< std::string, Quota > &))
virtual void suppressOffers(const FrameworkID &frameworkId, const std::set< std::string > &roles)=0
Suppresses offers.
MOCK_METHOD0(getInverseOfferStatuses, process::Future< hashmap< SlaveID, hashmap< FrameworkID, mesos::allocator::InverseOfferStatus >>>())
Definition: quota.hpp:27
virtual process::Future< Nothing > updateAvailable(const SlaveID &slaveId, const std::vector< Offer::Operation > &operations)=0
Updates available resources on an agent based on a sequence of offer operations.
Quota createQuota(const std::string &guarantees, const std::string &limits)
MOCK_METHOD1(removeFramework, void(const FrameworkID &))
virtual void updateInverseOffer(const SlaveID &slaveId, const FrameworkID &frameworkId, const Option< UnavailableResources > &unavailableResources, const Option< InverseOfferStatus > &status, const Option< Filters > &filters=None())=0
Updates inverse offer.
virtual void updateSlave(const SlaveID &slave, const SlaveInfo &slaveInfo, const Option< Resources > &total=None(), const Option< std::vector< SlaveInfo::Capability >> &capabilities=None())=0
Updates an agent.
MOCK_METHOD3(initialize, void(const Options &options, const lambda::function< void(const FrameworkID &, const hashmap< std::string, hashmap< SlaveID, Resources >> &)> &, const lambda::function< void(const FrameworkID &, const hashmap< SlaveID, UnavailableResources > &)> &))