Skip to content

Commit

Permalink
CS144 Lab 1 assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
keithw committed Sep 23, 2020
1 parent 0b238af commit c1471b9
Show file tree
Hide file tree
Showing 14 changed files with 1,157 additions and 4 deletions.
8 changes: 4 additions & 4 deletions etc/tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ add_test(NAME t_send_window COMMAND send_window)
add_test(NAME t_send_ack COMMAND send_ack)
add_test(NAME t_send_close COMMAND send_close)

add_test(NAME t_strm_reassem_cap COMMAND fsm_stream_reassembler_cap)
add_test(NAME t_strm_reassem_single COMMAND fsm_stream_reassembler_single)
add_test(NAME t_strm_reassem_seq COMMAND fsm_stream_reassembler_seq)
add_test(NAME t_strm_reassem_dup COMMAND fsm_stream_reassembler_dup)
add_test(NAME t_strm_reassem_holes COMMAND fsm_stream_reassembler_holes)
add_test(NAME t_strm_reassem_many COMMAND fsm_stream_reassembler_many)
add_test(NAME t_strm_reassem_overlapping COMMAND fsm_stream_reassembler_overlapping)
add_test(NAME t_strm_reassem_win COMMAND fsm_stream_reassembler_win)
add_test(NAME t_strm_reassem_cap COMMAND fsm_stream_reassembler_cap)

add_test(NAME t_byte_stream_construction COMMAND byte_stream_construction)
add_test(NAME t_byte_stream_one_write COMMAND byte_stream_one_write)
Expand Down Expand Up @@ -214,11 +214,11 @@ add_custom_target (check_webget COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failu
COMMENT "Testing webget...")
add_custom_target (check_lab0 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_webget|t_byte_stream|_dt'
COMMENT "Testing Lab 0...")
add_custom_target (check_lab1 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_strm_reassem_|t_webget|t_byte_stream|_dt'
add_custom_target (check_lab1 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_strm_reassem_|t_byte_stream|_dt'
COMMENT "Testing the stream reassembler...")
add_custom_target (check_lab2 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_recv_|t_wrapping_|t_strm_reassem_|t_webget|t_byte_stream|_dt'
add_custom_target (check_lab2 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_recv_|t_wrapping_|t_strm_reassem_|t_byte_stream|_dt'
COMMENT "Testing the TCP receiver...")
add_custom_target (check_lab3 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_send_|t_recv_|t_wrapping_|t_strm_reassem_|t_webget|t_byte_stream|_dt'
add_custom_target (check_lab3 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R 't_send_|t_recv_|t_wrapping_|t_strm_reassem_|t_byte_stream|_dt'
COMMENT "Testing the TCP sender...")
add_custom_target (check_lab4 COMMAND "${PROJECT_SOURCE_DIR}/tun.sh" check 144 145
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 10 -R "^t_"
Expand Down
26 changes: 26 additions & 0 deletions libsponge/stream_reassembler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "stream_reassembler.hh"

// Dummy implementation of a stream reassembler.

// For Lab 1, please replace with a real implementation that passes the
// automated checks run by `make check_lab1`.

// You will need to add private members to the class declaration in `stream_reassembler.hh`

template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}

using namespace std;

StreamReassembler::StreamReassembler(const size_t capacity) : _output(capacity), _capacity(capacity) {}

//! \details This function accepts a substring (aka a segment) of bytes,
//! possibly out-of-order, from the logical stream, and assembles any newly
//! contiguous substrings and writes them into the output stream in order.
void StreamReassembler::push_substring(const string &data, const size_t index, const bool eof) {
DUMMY_CODE(data, index, eof);
}

size_t StreamReassembler::unassembled_bytes() const { return {}; }

bool StreamReassembler::empty() const { return {}; }
51 changes: 51 additions & 0 deletions libsponge/stream_reassembler.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#define SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH

#include "byte_stream.hh"

#include <cstdint>
#include <string>

//! \brief A class that assembles a series of excerpts from a byte stream (possibly out of order,
//! possibly overlapping) into an in-order byte stream.
class StreamReassembler {
private:
// Your code here -- add private members as necessary.

ByteStream _output; //!< The reassembled in-order byte stream
size_t _capacity; //!< The maximum number of bytes

public:
//! \brief Construct a `StreamReassembler` that will store up to `capacity` bytes.
//! \note This capacity limits both the bytes that have been reassembled,
//! and those that have not yet been reassembled.
StreamReassembler(const size_t capacity);

//! \brief Receive a substring and write any newly contiguous bytes into the stream.
//!
//! The StreamReassembler will stay within the memory limits of the `capacity`.
//! Bytes that would exceed the capacity are silently discarded.
//!
//! \param data the substring
//! \param index indicates the index (place in sequence) of the first byte in `data`
//! \param eof the last byte of `data` will be the last byte in the entire stream
void push_substring(const std::string &data, const uint64_t index, const bool eof);

//! \name Access the reassembled byte stream
//!@{
const ByteStream &stream_out() const { return _output; }
ByteStream &stream_out() { return _output; }
//!@}

//! The number of bytes in the substrings stored but not yet reassembled
//!
//! \note If the byte at a particular index has been pushed more than once, it
//! should only be counted once for the purpose of this function.
size_t unassembled_bytes() const;

//! \brief Is the internal state empty (other than the output stream)?
//! \returns `true` if no substrings are waiting to be assembled
bool empty() const;
};

#endif // SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
8 changes: 8 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ macro (add_test_exec exec_name)
target_link_libraries ("${exec_name}" sponge ${ARGN})
endmacro (add_test_exec)

add_test_exec (fsm_stream_reassembler_single)
add_test_exec (fsm_stream_reassembler_seq)
add_test_exec (fsm_stream_reassembler_dup)
add_test_exec (fsm_stream_reassembler_holes)
add_test_exec (fsm_stream_reassembler_many)
add_test_exec (fsm_stream_reassembler_overlapping)
add_test_exec (fsm_stream_reassembler_win)
add_test_exec (fsm_stream_reassembler_cap)
add_test_exec (byte_stream_construction)
add_test_exec (byte_stream_one_write)
add_test_exec (byte_stream_two_writes)
Expand Down
82 changes: 82 additions & 0 deletions tests/fsm_stream_reassembler_cap.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "byte_stream.hh"
#include "fsm_stream_reassembler_harness.hh"
#include "stream_reassembler.hh"
#include "util.hh"

#include <exception>
#include <iostream>

using namespace std;

int main() {
try {
{
ReassemblerTestHarness test{2};

test.execute(SubmitSegment{"ab", 0});
test.execute(BytesAssembled(2));
test.execute(BytesAvailable("ab"));

test.execute(SubmitSegment{"cd", 2});
test.execute(BytesAssembled(4));
test.execute(BytesAvailable("cd"));

test.execute(SubmitSegment{"ef", 4});
test.execute(BytesAssembled(6));
test.execute(BytesAvailable("ef"));
}

{
ReassemblerTestHarness test{2};

test.execute(SubmitSegment{"ab", 0});
test.execute(BytesAssembled(2));

test.execute(SubmitSegment{"cd", 2});
test.execute(BytesAssembled(2));

test.execute(BytesAvailable("ab"));
test.execute(BytesAssembled(2));

test.execute(SubmitSegment{"cd", 2});
test.execute(BytesAssembled(4));

test.execute(BytesAvailable("cd"));
}

{
ReassemblerTestHarness test{1};

test.execute(SubmitSegment{"ab", 0});
test.execute(BytesAssembled(1));

test.execute(SubmitSegment{"ab", 0});
test.execute(BytesAssembled(1));

test.execute(BytesAvailable("a"));
test.execute(BytesAssembled(1));

test.execute(SubmitSegment{"abc", 0});
test.execute(BytesAssembled(2));

test.execute(BytesAvailable("b"));
test.execute(BytesAssembled(2));
}

{
ReassemblerTestHarness test{3};
for (unsigned int i = 0; i < 99997; i += 3) {
const string segment = {char(i), char(i + 1), char(i + 2), char(i + 13), char(i + 47), char(i + 9)};
test.execute(SubmitSegment{segment, i});
test.execute(BytesAssembled(i + 3));
test.execute(BytesAvailable(segment.substr(0, 3)));
}
}

} catch (const exception &e) {
cerr << "Exception: " << e.what() << endl;
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}
98 changes: 98 additions & 0 deletions tests/fsm_stream_reassembler_dup.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "byte_stream.hh"
#include "fsm_stream_reassembler_harness.hh"
#include "stream_reassembler.hh"
#include "util.hh"

#include <exception>
#include <iostream>

using namespace std;

int main() {
try {
auto rd = get_random_generator();

{
ReassemblerTestHarness test{65000};

test.execute(SubmitSegment{"abcd", 0});
test.execute(BytesAssembled(4));
test.execute(BytesAvailable("abcd"));
test.execute(NotAtEof{});

test.execute(SubmitSegment{"abcd", 0});
test.execute(BytesAssembled(4));
test.execute(BytesAvailable(""));
test.execute(NotAtEof{});
}

{
ReassemblerTestHarness test{65000};

test.execute(SubmitSegment{"abcd", 0});
test.execute(BytesAssembled(4));
test.execute(BytesAvailable("abcd"));
test.execute(NotAtEof{});

test.execute(SubmitSegment{"abcd", 4});
test.execute(BytesAssembled(8));
test.execute(BytesAvailable("abcd"));
test.execute(NotAtEof{});

test.execute(SubmitSegment{"abcd", 0});
test.execute(BytesAssembled(8));
test.execute(BytesAvailable(""));
test.execute(NotAtEof{});

test.execute(SubmitSegment{"abcd", 4});
test.execute(BytesAssembled(8));
test.execute(BytesAvailable(""));
test.execute(NotAtEof{});
}

{
ReassemblerTestHarness test{65000};

test.execute(SubmitSegment{"abcdefgh", 0});
test.execute(BytesAssembled(8));
test.execute(BytesAvailable("abcdefgh"));
test.execute(NotAtEof{});
string data = "abcdefgh";

for (size_t i = 0; i < 1000; ++i) {
size_t start_i = uniform_int_distribution<size_t>{0, 8}(rd);
auto start = data.begin();
std::advance(start, start_i);

size_t end_i = uniform_int_distribution<size_t>{start_i, 8}(rd);
auto end = data.begin();
std::advance(end, end_i);

test.execute(SubmitSegment{string{start, end}, start_i});
test.execute(BytesAssembled(8));
test.execute(BytesAvailable(""));
test.execute(NotAtEof{});
}
}

{
ReassemblerTestHarness test{65000};

test.execute(SubmitSegment{"abcd", 0});
test.execute(BytesAssembled(4));
test.execute(BytesAvailable("abcd"));
test.execute(NotAtEof{});

test.execute(SubmitSegment{"abcdef", 0});
test.execute(BytesAssembled(6));
test.execute(BytesAvailable("ef"));
test.execute(NotAtEof{});
}

} catch (const exception &e) {
cerr << "Exception: " << e.what() << endl;
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}
Loading

0 comments on commit c1471b9

Please sign in to comment.