blob: 786be185bbcf6844c8fc87ad1ba7dc59b6f96ccb [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <assert.h>
#include <list>
#include <vector>
#include "garnet/lib/overnet/vocabulary/internal_list.h"
namespace overnet {
namespace internal_list {
class Fuzzer {
public:
bool PushBack(uint8_t node, uint8_t list) {
TestNode* n = &nodes_[node];
switch (list) {
default:
return false;
case 1:
if (n->in1)
return false;
n->in1 = true;
list1_.PushBack(n);
mirror1_.push_back(n);
break;
case 2:
if (n->in2)
return false;
n->in2 = true;
list2_.PushBack(n);
mirror2_.push_back(n);
break;
case 3:
if (n->in3)
return false;
n->in3 = true;
list3_.PushBack(n);
mirror3_.push_back(n);
break;
case 4:
if (n->in4)
return false;
n->in4 = true;
list4_.PushBack(n);
mirror4_.push_back(n);
break;
case 5:
if (n->in5)
return false;
n->in5 = true;
list5_.PushBack(n);
mirror5_.push_back(n);
break;
case 6:
if (n->in6)
return false;
n->in6 = true;
list6_.PushBack(n);
mirror6_.push_back(n);
break;
case 7:
if (n->in7)
return false;
n->in7 = true;
list7_.PushBack(n);
mirror7_.push_back(n);
break;
}
return true;
}
bool PushFront(uint8_t node, uint8_t list) {
TestNode* n = &nodes_[node];
switch (list) {
default:
return false;
case 1:
if (n->in1)
return false;
n->in1 = true;
list1_.PushFront(n);
mirror1_.push_front(n);
break;
case 2:
if (n->in2)
return false;
n->in2 = true;
list2_.PushFront(n);
mirror2_.push_front(n);
break;
case 3:
if (n->in3)
return false;
n->in3 = true;
list3_.PushFront(n);
mirror3_.push_front(n);
break;
case 4:
if (n->in4)
return false;
n->in4 = true;
list4_.PushFront(n);
mirror4_.push_front(n);
break;
case 5:
if (n->in5)
return false;
n->in5 = true;
list5_.PushFront(n);
mirror5_.push_front(n);
break;
case 6:
if (n->in6)
return false;
n->in6 = true;
list6_.PushFront(n);
mirror6_.push_front(n);
break;
case 7:
if (n->in7)
return false;
n->in7 = true;
list7_.PushFront(n);
mirror7_.push_front(n);
break;
}
return true;
}
bool Remove(uint8_t node, uint8_t list) {
TestNode* n = &nodes_[node];
switch (list) {
default:
return false;
case 1:
if (!n->in1)
return false;
n->in1 = false;
list1_.Remove(n);
mirror1_.remove(n);
break;
case 2:
if (!n->in2)
return false;
n->in2 = false;
list2_.Remove(n);
mirror2_.remove(n);
break;
case 3:
if (!n->in3)
return false;
n->in3 = false;
list3_.Remove(n);
mirror3_.remove(n);
break;
case 4:
if (!n->in4)
return false;
n->in4 = false;
list4_.Remove(n);
mirror4_.remove(n);
break;
case 5:
if (!n->in5)
return false;
n->in5 = false;
list5_.Remove(n);
mirror5_.remove(n);
break;
case 6:
if (!n->in6)
return false;
n->in6 = false;
list6_.Remove(n);
mirror6_.remove(n);
break;
case 7:
if (!n->in7)
return false;
n->in7 = false;
list7_.Remove(n);
mirror7_.remove(n);
break;
}
return true;
}
void Verify() {
auto f1a = Flatten(list1_);
auto f1b = Flatten(mirror1_);
auto f2a = Flatten(list2_);
auto f2b = Flatten(mirror2_);
auto f3a = Flatten(list3_);
auto f3b = Flatten(mirror3_);
auto f4a = Flatten(list4_);
auto f4b = Flatten(mirror4_);
auto f5a = Flatten(list5_);
auto f5b = Flatten(mirror5_);
auto f6a = Flatten(list6_);
auto f6b = Flatten(mirror6_);
auto f7a = Flatten(list7_);
auto f7b = Flatten(mirror7_);
assert(f1a == f1b);
assert(f2a == f2b);
assert(f3a == f3b);
assert(f4a == f4b);
assert(f5a == f5b);
assert(f6a == f6b);
assert(f7a == f7b);
assert(list1_.Front() == mirror1_.front());
assert(list2_.Front() == mirror2_.front());
assert(list3_.Front() == mirror3_.front());
assert(list4_.Front() == mirror4_.front());
assert(list5_.Front() == mirror5_.front());
assert(list6_.Front() == mirror6_.front());
assert(list7_.Front() == mirror7_.front());
assert(list1_.Size() == mirror1_.size());
assert(list2_.Size() == mirror2_.size());
assert(list3_.Size() == mirror3_.size());
assert(list4_.Size() == mirror4_.size());
assert(list5_.Size() == mirror5_.size());
assert(list6_.Size() == mirror6_.size());
assert(list7_.Size() == mirror7_.size());
}
private:
template <class T>
std::vector<uint16_t> Flatten(T& t) {
std::vector<uint16_t> out;
for (auto i : t) {
out.push_back(i - nodes_);
}
return out;
}
struct TestNode {
bool in1 = false;
bool in2 = false;
bool in3 = false;
bool in4 = false;
bool in5 = false;
bool in6 = false;
bool in7 = false;
InternalListNode<TestNode> link1;
InternalListNode<TestNode> link2;
InternalListNode<TestNode> link3;
InternalListNode<TestNode> link4;
InternalListNode<TestNode> link5;
InternalListNode<TestNode> link6;
InternalListNode<TestNode> link7;
};
TestNode nodes_[256];
InternalList<TestNode, &TestNode::link1> list1_;
InternalList<TestNode, &TestNode::link2> list2_;
InternalList<TestNode, &TestNode::link3> list3_;
InternalList<TestNode, &TestNode::link4> list4_;
InternalList<TestNode, &TestNode::link5> list5_;
InternalList<TestNode, &TestNode::link6> list6_;
InternalList<TestNode, &TestNode::link7> list7_;
std::list<TestNode*> mirror1_;
std::list<TestNode*> mirror2_;
std::list<TestNode*> mirror3_;
std::list<TestNode*> mirror4_;
std::list<TestNode*> mirror5_;
std::list<TestNode*> mirror6_;
std::list<TestNode*> mirror7_;
};
} // namespace internal_list
} // namespace overnet