blob: 8b04208e3f4ad4ead3c75de3cdb91904e0efbbfd [file] [log] [blame]
// Copyright 2019 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.
#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include "src/bringup/bin/netsvc/netboot.h"
#include "src/bringup/bin/netsvc/netsvc.h"
#include "src/bringup/bin/netsvc/test/paver-test-common.h"
void update_timeouts() {}
bool netbootloader() { return false; }
bool all_features() { return true; }
const char* nodename() { return "test"; }
void netboot_run_cmd(const char* cmd) {}
void udp6_recv(void* data, size_t len, const ip6_addr_t* daddr, uint16_t dport,
const ip6_addr_t* saddr, uint16_t sport) {}
void netifc_recv(void* data, size_t len) {}
bool netifc_send_pending() { return false; }
namespace {
// We attempt to write more data than we have memory to ensure we are not keeping the file in memory
// the entire time.
TEST_F(PaverTest, WriteFvmManyLargeWrites) {
constexpr size_t kChunkSize = 1 << 20; // 1MiB
auto fake_data = std::make_unique<uint8_t[]>(kChunkSize);
memset(fake_data.get(), 0x4F, kChunkSize);
const size_t payload_size = zx_system_get_physmem();
fake_svc_.fake_paver().set_expected_payload_size(payload_size);
fake_svc_.fake_paver().set_wait_for_start_signal(true);
ASSERT_EQ(paver_.OpenWrite(NETBOOT_FVM_SPARSE_FILENAME, payload_size, zx::duration::infinite()),
TFTP_NO_ERROR);
loop_.StartThread();
auto cleanup = fit::defer(fit::bind_member<&async::Loop::Shutdown>(&loop_));
for (size_t offset = 0; offset < payload_size; offset += kChunkSize) {
size_t size = std::min(kChunkSize, payload_size - offset);
ASSERT_EQ(paver_.Write(fake_data.get(), &size, offset), TFTP_NO_ERROR);
ASSERT_EQ(size, std::min(kChunkSize, payload_size - offset));
// Stop and wait for all the data to be consumed, as we write data much faster than it can be
// consumed.
if ((offset / kChunkSize) % 100 == 0) {
fake_svc_.fake_paver().WaitForWritten(offset);
}
}
fake_svc_.fake_paver().WaitForWritten(payload_size + 1);
paver_.Close();
ASSERT_OK(paver_.exit_code().get());
ASSERT_EQ(fake_svc_.fake_paver().GetCommandTrace(),
std::vector<paver_test::Command>{paver_test::Command::kWriteVolumes});
}
} // namespace