132 lines
3.1 KiB
C
132 lines
3.1 KiB
C
|
/*
|
||
|
* Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
|
||
|
*
|
||
|
* Licensed under the BSD License, see LICENSE file for details.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef CPP_TEST_COMMON_DROP_RULES_H_
|
||
|
#define CPP_TEST_COMMON_DROP_RULES_H_
|
||
|
|
||
|
namespace xtreemfs {
|
||
|
namespace rpc {
|
||
|
|
||
|
/** This interface is used for arbitrary implementations of drop rules
|
||
|
* for RPC requests processed by TestRPCServer.
|
||
|
*/
|
||
|
class DropRule {
|
||
|
public:
|
||
|
/** This method is called for every received process */
|
||
|
virtual bool DropRequest(uint32_t proc_id) = 0;
|
||
|
|
||
|
/** This method is used to determine whether or not a rule can be deleted */
|
||
|
virtual bool IsPointless() const = 0;
|
||
|
|
||
|
/** Helper predicate function for std::algorithm */
|
||
|
static bool IsPointlessPred(const DropRule* rule) {
|
||
|
return rule->IsPointless();
|
||
|
}
|
||
|
|
||
|
virtual ~DropRule() {};
|
||
|
};
|
||
|
|
||
|
/** This rule skips m requests before dropping n requests. Afterwards, the rule
|
||
|
* becomes pointless. The proc_id is not checked.
|
||
|
*/
|
||
|
class SkipMDropNRule : public DropRule {
|
||
|
public:
|
||
|
SkipMDropNRule(size_t skip, size_t drop) : skip_count_(skip), drop_count_(drop) {}
|
||
|
|
||
|
virtual bool DropRequest(uint32_t proc_id) {
|
||
|
if (skip_count_ == 0 && drop_count_ > 0) {
|
||
|
--drop_count_;
|
||
|
return true;
|
||
|
} else if (skip_count_ > 0) {
|
||
|
--skip_count_;
|
||
|
}
|
||
|
return false;
|
||
|
// or just:
|
||
|
// return skip_count_-- > 0 ? ++skip_count_ : drop_count_-- > 0 ? true : ++drop_count_;
|
||
|
}
|
||
|
|
||
|
virtual bool IsPointless() const {
|
||
|
return (drop_count_ == 0) && (skip_count_ == 0);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
size_t skip_count_;
|
||
|
size_t drop_count_;
|
||
|
};
|
||
|
|
||
|
/** This rule is used in combination with another rule which will be only
|
||
|
* called when the proc_id passed to DropRequest matches the one passed
|
||
|
* to the ctor.
|
||
|
*/
|
||
|
class ProcIDFilterRule : public DropRule {
|
||
|
public:
|
||
|
/** Construct a proc_id filtered rule from an existing rule.
|
||
|
* The ownership of rule's pointee is transfered to the created instance.
|
||
|
*/
|
||
|
ProcIDFilterRule(uint32_t proc_id, DropRule* rule)
|
||
|
: proc_id_(proc_id), rule_(rule) {}
|
||
|
|
||
|
virtual bool DropRequest(uint32_t proc_id) {
|
||
|
return proc_id == proc_id_ ? rule_->DropRequest(proc_id) : false;
|
||
|
}
|
||
|
|
||
|
virtual bool IsPointless() const {
|
||
|
return rule_->IsPointless();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
uint32_t proc_id_;
|
||
|
boost::scoped_ptr<DropRule> rule_;
|
||
|
};
|
||
|
|
||
|
/** This rule drops n requests without checking the proc_id. */
|
||
|
class DropNRule : public DropRule {
|
||
|
public:
|
||
|
DropNRule(size_t count) : count_(count) {}
|
||
|
|
||
|
virtual bool DropRequest(uint32_t proc_id) {
|
||
|
if (count_ > 0) {
|
||
|
--count_;
|
||
|
return true;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual bool IsPointless() const {
|
||
|
return count_ == 0;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
size_t count_;
|
||
|
};
|
||
|
|
||
|
/** This rule drops all rules with a certain proc_id. This rule will never
|
||
|
* become pointless.
|
||
|
*/
|
||
|
class DropByProcIDRule : public DropRule {
|
||
|
public:
|
||
|
DropByProcIDRule(uint32_t proc_id)
|
||
|
: proc_id_(proc_id) {}
|
||
|
|
||
|
virtual bool DropRequest(uint32_t proc_id) {
|
||
|
return proc_id_ == proc_id;
|
||
|
}
|
||
|
|
||
|
virtual bool IsPointless() const {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
size_t proc_id_;
|
||
|
};
|
||
|
|
||
|
} // namespace rpc
|
||
|
} // namespace xtreemfs
|
||
|
|
||
|
#endif
|