fs_report.run: replace test with dedicated program

The new version of the test exercises the combination of fs_report with
ram_fs and fs_rom as a more flexible alternative to report_rom.

It covers two corner cases that remained unaddressed by fs_rom and
ram_fs so far: First, the late installation of a ROM-update signal
handler at fs_rom right before the content of the file is modified.
Second, the case where the requested file is not present on the file
system at the creation time of the ROM session. Here, the ram_fs missed
to inform listeners for the compound directory about the later created
file.
This commit is contained in:
Norman Feske 2017-06-28 14:20:48 +02:00 committed by Christian Helmuth
parent d649451c3d
commit 7d12d7a78f
4 changed files with 175 additions and 49 deletions

View File

@ -2,10 +2,8 @@
# Build
#
set build_components {
core init
drivers/timer
server/fs_report
server/vfs
core init drivers/timer
server/fs_report server/fs_rom server/ram_fs test/fs_report
}
build $build_components
@ -18,67 +16,61 @@ create_boot_directory
append config {
<config>
<parent-provides>
<service name="CPU"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="IRQ"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="PD"/>
<service name="RM"/>
<service name="ROM"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="1024"/>
<default caps="100"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides ><service name="Timer"/> </provides>
<provides> <service name="Timer"/> </provides>
</start>
<start name="log_fs">
<binary name="vfs"/>
<start name="ram_fs">
<resource name="RAM" quantum="4M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <dir name="init"> <log name="state"/> <ram/> </dir> </vfs>
<policy label_prefix="fs_report" writeable="yes"/>
<content>
<dir name="test-fs_report">
<inline name="devices">
<devices version="initial"/>
</inline>
</dir>
</content>
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
</config>
</start>
<!--
All reports sent by 'test-fs_report' are prefixed with the label of the
component. Hence, they are written to the 'test-fs_report/' subdirectory.
-->
<start name="fs_report">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Report"/> </provides>
<config>
<vfs> <fs/> </vfs>
</config>
<config> <vfs> <fs/> </vfs> </config>
</start>
<start name="init">
<resource name="RAM" quantum="8M"/>
<provides><service name="ROM"/></provides>
<config>
<parent-provides>
<service name="CPU"/>
<service name="LOG"/>
<service name="PD"/>
<service name="RAM"/>
<service name="RM"/>
<service name="ROM"/>
<service name="Report"/>
<service name="Timer"/>
</parent-provides>
<default-route>
<any-service> <parent/> </any-service>
</default-route>
<report init_caps="yes" child_caps="yes" init_ram="yes" ids="yes" requested="yes" provided="yes" session_args="yes" child_ram="yes"/>
<start name="init" caps="512">
<start name="fs_rom">
<resource name="RAM" quantum="4M"/>
<provides><service name="ROM"/></provides>
<config>
<report init_caps="yes" child_caps="yes" init_ram="yes" ids="yes" requested="yes" provided="yes" session_args="yes" child_ram="yes"/>
</config>
<provides> <service name="ROM"/> </provides>
<config/>
</start>
</config>
<start name="test-fs_report">
<resource name="RAM" quantum="4M"/>
<config/>
<route>
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
<service name="ROM" label="focus"> <child name="fs_rom"/> </service>
<service name="Report" label="devices"> <child name="fs_report"/> </service>
<service name="Report" label="focus"> <child name="fs_report"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>}
@ -87,17 +79,13 @@ install_config $config
#
# Boot modules
#
# generic modules
set boot_modules {
core ld.lib.so init
fs_report
timer
vfs
core ld.lib.so init timer
fs_report fs_rom ram_fs test-fs_report
}
build_boot_image $boot_modules
append qemu_args " -nographic"
run_genode_until {.*</state>.*} 20
run_genode_until {child "test-fs_report" exited with exit value 0.*\n} 30

View File

@ -0,0 +1,133 @@
/*
* \brief Test for combining ram_fs, fs_rom, and fs_report
* \author Norman Feske
* \date 2017-06-28
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/log.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <timer_session/connection.h>
namespace Test {
struct Main;
using namespace Genode;
}
struct Test::Main
{
Env &_env;
Timer::Connection _timer { _env };
Constructible<Reporter> _devices_reporter;
Constructible<Reporter> _focus_reporter;
typedef String<80> Version;
void _report(Reporter &reporter, Version const &version)
{
Reporter::Xml_generator xml(reporter, [&] () {
xml.attribute("version", version); });
}
Constructible<Attached_rom_dataspace> _devices_rom;
Constructible<Attached_rom_dataspace> _focus_rom;
Signal_handler<Main> _devices_rom_update_handler {
_env.ep(), *this, &Main::_handle_devices_rom_update };
Signal_handler<Main> _focus_rom_update_handler {
_env.ep(), *this, &Main::_handle_focus_rom_update };
Constructible<Timer::One_shot_timeout<Main> > _one_shot_timeout;
void _handle_init()
{
log("(1) check initial content of \"devices\" ROM");
_devices_rom.construct(_env, "devices");
if (_devices_rom->xml().attribute_value("version", Version()) != "initial") {
error("ROM does not contain expected initial conent");
throw Exception();
}
log("(2) issue new \"devices\" report before installing a ROM signal handler");
_devices_reporter.construct(_env, "devices");
_devices_reporter->enabled(true);
_report(*_devices_reporter, "version 2");
log("(3) wait a bit to let the report reach the RAM fs");
_one_shot_timeout.construct(_timer, *this, &Main::_handle_timer_1);
_one_shot_timeout->schedule(Microseconds(500*1000));
}
void _handle_timer_1(Duration)
{
log("(4) install ROM signal handler, is expected to trigger immediately");
_devices_rom->sigh(_devices_rom_update_handler);
}
void _handle_devices_rom_update()
{
log("(5) received ROM update as expected");
_devices_rom->update();
if (_devices_rom->xml().attribute_value("version", Version()) != "version 2") {
error("unexpected content of \"devices\" ROM after update");
throw Exception();
}
log("(6) request not-yet-available \"focus\" ROM");
_focus_rom.construct(_env, "focus");
_focus_rom->sigh(_focus_rom_update_handler);
log("(7) wait a bit until generating the focus report");
_one_shot_timeout.construct(_timer, *this, &Main::_handle_timer_2);
_one_shot_timeout->schedule(Microseconds(500*1000));
}
void _handle_timer_2(Duration)
{
log("(8) generate \"focus\" report, is expected to trigger ROM notification");
_focus_reporter.construct(_env, "focus");
_focus_reporter->enabled(true);
_report(*_focus_reporter, "focus version 1");
}
void _handle_focus_rom_update()
{
_focus_rom->update();
if (_focus_rom->xml().attribute_value("version", Version()) != "focus version 1") {
error("unexpected content of \"focus\" ROM");
throw Exception();
}
log("(9) received expected focus ROM content");
/* test completed successfully */
_env.parent().exit(0);
}
Main(Env &env) : _env(env)
{
log("--- test-fs_report started ---");
_handle_init();
}
};
void Component::construct(Genode::Env &env) { static Test::Main main(env); }

View File

@ -0,0 +1,4 @@
TARGET = test-fs_report
SRC_CC = main.cc
LIBS = base

View File

@ -105,3 +105,4 @@ init
nic_dump
slab
ada
fs_report