forked from huangrt01/TCP-Lab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tcp_expectation_forward.hh
91 lines (80 loc) · 3.39 KB
/
tcp_expectation_forward.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef SPONGE_LIBSPONGE_TCP_EXPECTATION_FORWARD_HH
#define SPONGE_LIBSPONGE_TCP_EXPECTATION_FORWARD_HH
#include "tcp_segment.hh"
#include "tcp_state.hh"
#include <cstdint>
#include <exception>
#include <optional>
#include <sstream>
class TCPTestHarness;
struct TCPTestStep {
public:
virtual ~TCPTestStep() {}
virtual std::string to_string() const { return "TestStep"; }
virtual void execute(TCPTestHarness &) const {}
virtual TCPSegment expect_seg(TCPTestHarness &) const { throw std::runtime_error("unimplemented"); }
};
struct TCPExpectation;
struct ExpectNoSegment;
struct ExpectState;
struct ExpectNotInState;
struct ExpectOneSegment;
struct ExpectSegment;
struct ExpectData;
struct ExpectNoData;
struct ExpectSegmentAvailable;
struct ExpectBytesInFlight;
struct ExpectUnassembledBytes;
struct ExpectWaitTimer;
struct SendSegment;
struct Write;
struct Tick;
struct Connect;
struct Listen;
struct Close;
class TCPExpectationViolation : public std::runtime_error {
public:
TCPExpectationViolation(const std::string msg) : std::runtime_error(msg) {}
};
class TCPPropertyViolation : public TCPExpectationViolation {
public:
TCPPropertyViolation(const std::string &msg) : TCPExpectationViolation(msg) {}
template <typename T>
static TCPPropertyViolation make(const std::string &property_name, const T &expected_value, const T &actual_value) {
std::stringstream ss{};
ss << "The TCP has `" << property_name << " = " << actual_value << "`, but " << property_name
<< " was expected to be `" << expected_value << "`";
return TCPPropertyViolation{ss.str()};
}
template <typename T>
static TCPPropertyViolation make_not(const std::string &property_name, const T &expected_non_value) {
std::stringstream ss{};
ss << "The TCP has `" << property_name << " = " << expected_non_value << "`, but " << property_name
<< " was expected to **not** be `" << expected_non_value << "`";
return TCPPropertyViolation{ss.str()};
}
};
class SegmentExpectationViolation : public TCPExpectationViolation {
public:
SegmentExpectationViolation(const std::string &msg) : TCPExpectationViolation(msg) {}
static SegmentExpectationViolation violated_verb(const std::string &msg) {
return SegmentExpectationViolation{"The TCP should have produced a segment that " + msg + ", but it did not"};
}
template <typename T>
static SegmentExpectationViolation violated_field(const std::string &field_name,
const T &expected_value,
const T &actual_value) {
std::stringstream ss{};
ss << "The TCP produced a segment with `" << field_name << " = " << actual_value << "`, but " << field_name
<< " was expected to be `" << expected_value << "`";
return SegmentExpectationViolation{ss.str()};
}
};
class StateExpectationViolation : public TCPExpectationViolation {
public:
StateExpectationViolation(const std::string &msg) : TCPExpectationViolation(msg) {}
StateExpectationViolation(const TCPState &expected_state, const TCPState &actual_state)
: TCPExpectationViolation("The TCP was in state `" + actual_state.name() +
"`, but it was expected to be in state `" + expected_state.name() + "`") {}
};
#endif // SPONGE_LIBSPONGE_TCP_EXPECTATION_FORWARD_HH