Skip to content

Commit

Permalink
pw_transfer: Add client read tests
Browse files Browse the repository at this point in the history
Extends the pw_transfer integration tests to include client
read-from-server tests.

Bug: b/234875234, b/250976246
Cq-Include-Trybots: luci.pigweed.try:pigweed-integration-transfer
Change-Id: Id21791ed18901fa660897ca4f205a51a758ca408
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/95042
Reviewed-by: Ted Pudlik <[email protected]>
Commit-Queue: Armando Montanez <[email protected]>
Pigweed-Auto-Submit: Armando Montanez <[email protected]>
  • Loading branch information
armandomontanez authored and CQ Bot Account committed Oct 5, 2022
1 parent 24c4722 commit 07fe68b
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 43 deletions.
1 change: 1 addition & 0 deletions pw_transfer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ pw_executable("integration_test_server") {
]
}

# TODO(b/234875234): This test is deprecated and will be removed.
pw_executable("integration_test") {
sources = [ "integration_test.cc" ]
deps = [
Expand Down
16 changes: 3 additions & 13 deletions pw_transfer/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ using namespace std::chrono_literals;

constexpr int kIterations = 5;

constexpr auto kData512 = bytes::Initialized<512>([](size_t i) { return i; });
constexpr auto kData8192 = bytes::Initialized<8192>([](size_t i) { return i; });
constexpr auto kDataHdlcEscape = bytes::Initialized<8192>(0x7e);

std::filesystem::path directory;

class Bernoulli {
Expand Down Expand Up @@ -163,8 +159,6 @@ ConstByteSpan AsByteSpan(const char (&data)[kLengthWithNull]) {
return as_bytes(span(data, kLength));
}

constexpr ConstByteSpan AsByteSpan(ConstByteSpan data) { return data; }

thread::Options& TransferThreadOptions() {
static thread::stl::Options options;
return options;
Expand Down Expand Up @@ -249,8 +243,9 @@ class TransferIntegration : public ::testing::Test {
return last_status_;
}

// Exact match the size of kData8192 to test filling the receiving buffer.
stream::MemoryWriterBuffer<kData8192.size()> read_buffer_;
// Aribitrary non-zero buffer size; all non-zero sized transfer tests have
// been migrated out of this test.
stream::MemoryWriterBuffer<1024> read_buffer_;

Client& client() { return client_; }

Expand Down Expand Up @@ -306,11 +301,6 @@ TEST_F(TransferIntegration, Read_UnknownId) {
static_assert(true, "Semicolons are required")

PW_TRANSFER_TEST_READ(Empty, "");
PW_TRANSFER_TEST_READ(SingleByte_1, "\0");
PW_TRANSFER_TEST_READ(SingleByte_2, "?");
PW_TRANSFER_TEST_READ(SmallData, "hunter2");
PW_TRANSFER_TEST_READ(LargeData, kData512);
PW_TRANSFER_TEST_READ(VeryLargeData, kData8192);

TEST_F(TransferIntegration, Write_UnknownId) {
constexpr std::byte kData[] = {std::byte{0}, std::byte{1}, std::byte{2}};
Expand Down
79 changes: 76 additions & 3 deletions pw_transfer/integration_test/cross_language_large_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ def test_3mb_write_dropped_data(self, client_type):
]""", config_pb2.ProxyConfig())

payload = random.Random(1649963713563718437).randbytes(3 * 1024 * 1024)

resource_id = 12

config = TransferConfig(server_config, client_config, proxy_config)
self.do_single_write(client_type, config, resource_id, payload)

Expand Down Expand Up @@ -121,11 +119,86 @@ def test_3mb_write_reordered_data(self, client_type):
]""", config_pb2.ProxyConfig())

payload = random.Random(1649963713563718437).randbytes(3 * 1024 * 1024)
resource_id = 12
config = TransferConfig(server_config, client_config, proxy_config)
self.do_single_write(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
# TODO(b/250976246): This test runs indefinitely (>24 hrs) when using
# the java client, so it is disabled for now until the issue is
# diagnosed.
# ("java"),
("python"),
])
def test_3mb_read_dropped_data(self, client_type):
server_config = config_pb2.ServerConfig(
chunk_size_bytes=216,
pending_bytes=32 * 1024,
chunk_timeout_seconds=5,
transfer_service_retries=4,
extend_window_divisor=32,
)
client_config = config_pb2.ClientConfig(
max_retries=5,
initial_chunk_timeout_ms=10000,
chunk_timeout_ms=4000,
)
proxy_config = text_format.Parse(
"""
client_filter_stack: [
{ rate_limiter: {rate: 50000} },
{ hdlc_packetizer: {} },
{ data_dropper: {rate: 0.01, seed: 1649963713563718435} }
]
server_filter_stack: [
{ rate_limiter: {rate: 50000} },
{ hdlc_packetizer: {} },
{ data_dropper: {rate: 0.01, seed: 1649963713563718436} }
]""", config_pb2.ProxyConfig())

payload = random.Random(1649963713563718437).randbytes(3 * 1024 * 1024)
resource_id = 12
config = TransferConfig(server_config, client_config, proxy_config)
self.do_single_read(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_3mb_read_reordered_data(self, client_type):
server_config = config_pb2.ServerConfig(
chunk_size_bytes=216,
pending_bytes=32 * 1024,
chunk_timeout_seconds=5,
transfer_service_retries=4,
extend_window_divisor=32,
)
client_config = config_pb2.ClientConfig(
max_retries=5,
initial_chunk_timeout_ms=10000,
chunk_timeout_ms=4000,
)
proxy_config = text_format.Parse(
"""
client_filter_stack: [
{ rate_limiter: {rate: 50000} },
{ hdlc_packetizer: {} },
{ data_transposer: {rate: 0.005, timeout: 0.5, seed: 1649963713563718435} }
]
server_filter_stack: [
{ rate_limiter: {rate: 50000} },
{ hdlc_packetizer: {} },
{ data_transposer: {rate: 0.005, timeout: 0.5, seed: 1649963713563718435} }
]""", config_pb2.ProxyConfig())

payload = random.Random(1649963713563718437).randbytes(3 * 1024 * 1024)
resource_id = 12
config = TransferConfig(server_config, client_config, proxy_config)
self.do_single_write(client_type, config, resource_id, payload)
self.do_single_read(client_type, config, resource_id, payload)


if __name__ == '__main__':
Expand Down
22 changes: 22 additions & 0 deletions pw_transfer/integration_test/cross_language_medium_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,28 @@ def test_large_hdlc_escape_client_write(self, client_type):
resource_id = 5
self.do_single_write(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_medium_client_read(self, client_type):
payload = random.Random(67336391945).randbytes(512)
config = self.default_config()
resource_id = 5
self.do_single_read(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_large_hdlc_escape_client_read(self, client_type):
payload = b"~" * 98731
config = self.default_config()
resource_id = 5
self.do_single_read(client_type, config, resource_id, payload)


if __name__ == '__main__':
test_fixture.run_tests_for(MediumTransferIntegrationTest)
33 changes: 33 additions & 0 deletions pw_transfer/integration_test/cross_language_small_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,39 @@ def test_small_client_write(self, client_type):
resource_id = 5
self.do_single_write(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_null_byte_client_read(self, client_type):
payload = b"\0"
config = self.default_config()
resource_id = 5
self.do_single_read(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_single_byte_client_read(self, client_type):
payload = b"?"
config = self.default_config()
resource_id = 5
self.do_single_read(client_type, config, resource_id, payload)

@parameterized.expand([
("cpp"),
("java"),
("python"),
])
def test_small_client_read(self, client_type):
payload = b"some data"
config = self.default_config()
resource_id = 5
self.do_single_read(client_type, config, resource_id, payload)


if __name__ == '__main__':
test_fixture.run_tests_for(SmallTransferIntegrationTest)
1 change: 1 addition & 0 deletions pw_transfer/py/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pw_python_package("py") {
proto_library = "..:proto"
}

# TODO(b/234875234): This test is deprecated and will be removed.
pw_python_script("python_cpp_transfer_test") {
sources = [ "tests/python_cpp_transfer_test.py" ]
python_deps = [
Expand Down
27 changes: 0 additions & 27 deletions pw_transfer/py/tests/python_cpp_transfer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,6 @@ def test_read_empty(self) -> None:
self.set_content(24, '')
self.assertEqual(self.manager.read(24), b'')

def test_read_single_byte(self) -> None:
for _ in range(ITERATIONS):
self.set_content(25, '0')
self.assertEqual(self.manager.read(25), b'0')

def test_read_small_amount_of_data(self) -> None:
for _ in range(ITERATIONS):
self.set_content(26, 'hunter2')
self.assertEqual(self.manager.read(26), b'hunter2')

def test_read_large_amount_of_data(self) -> None:
for _ in range(ITERATIONS):
size = 2**13 # TODO(hepler): Increase to 2**14 when it passes.
self.set_content(27, '~' * size)
self.assertEqual(self.manager.read(27), b'~' * size)

def test_write_unknown_id(self) -> None:
with self.assertRaises(pw_transfer.Error) as ctx:
self.manager.write(99, '')
Expand Down Expand Up @@ -243,11 +227,6 @@ def write_very_large_amount_of_data(self) -> None:
self.manager.write(32, _DATA_4096B)
self.assertEqual(self.get_content(32), _DATA_4096B)

def test_packet_loss_during_read(self) -> None:
self._incoming_filter.dropped_packet_probability = 0.1
self._outgoing_filter.dropped_packet_probability = 0.1
self.read_large_amount_of_data()

def test_packet_delay_during_read(self) -> None:
self._incoming_filter.delayed_packet_probability = 0.1
self._outgoing_filter.delayed_packet_probability = 0.1
Expand All @@ -269,12 +248,6 @@ def test_packet_duplication_during_write(self) -> None:
self._outgoing_filter.duplicated_packet_probability = 0.1
self.write_very_large_amount_of_data()

def test_packet_reordering_during_read(self) -> None:
# TODO(amontanez): At 0.05 this fails.
self._incoming_filter.out_of_order_probability = 0.01
self._outgoing_filter.out_of_order_probability = 0.01
self.read_large_amount_of_data()


def _main(test_server_command: List[str], port: int,
unittest_args: List[str]) -> None:
Expand Down

0 comments on commit 07fe68b

Please sign in to comment.