Skip to content

Commit

Permalink
Add umockdev_testbed_load_script_from_string()
Browse files Browse the repository at this point in the history
This makes it more comfortable to deal with lots of small hand-crafted
scripts instead of few big records.
  • Loading branch information
martinpitt committed Dec 26, 2024
1 parent b98dfde commit 1243389
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 26 deletions.
37 changes: 33 additions & 4 deletions src/umockdev.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1034,8 +1034,37 @@ public class Testbed: GLib.Object {
public bool load_script (string? dev, string recordfile)
throws GLib.Error, FileError, IOError, RegexError
{
var script = new DataInputStream(File.new_for_path(recordfile).read());
return this.load_script_from_stream(dev,
new DataInputStream(File.new_for_path(recordfile).read()),
recordfile);
}

/**
* umockdev_testbed_load_script_from_string:
* @self: A #UMockdevTestbed.
* @dev: Device path (/dev/...) for which to load the script record.
* %NULL is valid; in this case the script is associated with
* the device node it was recorded from.
* @script: script string
* @error: return location for a GError, or %NULL
*
* Load a script record file for a particular device into the testbed.
* script records can be created with umockdev-record --script.
*
* Returns: %TRUE on success, %FALSE if @recordfile is invalid and an error
* occurred.
*/
public bool load_script_from_string (string? dev, string script)
throws GLib.Error, IOError, RegexError
{
return this.load_script_from_stream(dev,
new DataInputStream(new MemoryInputStream.from_data(script.data)),
"<string>");
}

private bool load_script_from_stream (string? dev, DataInputStream script, string scriptname)
throws GLib.Error, IOError, RegexError
{
string? owned_dev = dev;
if (owned_dev == null) {

Expand All @@ -1046,11 +1075,11 @@ public class Testbed: GLib.Object {

// Next must be our d 0 <devicenode> header
if (line == null)
error("script %s has no non-comment content", recordfile);
error("script %s has no non-comment content", scriptname);

MatchInfo header_matcher;
if (!(new Regex("^d 0 (.*)(\n|$)")).match(line, 0, out header_matcher))
error("null passed for device node, but script %s has no d 0 header", recordfile);
error("null passed for device node, but script %s has no d 0 header", scriptname);
owned_dev = header_matcher.fetch(1);
}

Expand All @@ -1060,7 +1089,7 @@ public class Testbed: GLib.Object {
if (fd < 0)
throw new FileError.INVAL (owned_dev + " is not a device suitable for scripts");

this.dev_script_runner.insert (owned_dev, new ScriptRunner (fd, owned_dev, script, recordfile));
this.dev_script_runner.insert (owned_dev, new ScriptRunner (fd, owned_dev, script, scriptname));
return true;
}

Expand Down
39 changes: 17 additions & 22 deletions tests/test-umockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,8 +1840,6 @@ t_testbed_script_replay_wait(UMockdevTestbedFixture * fixture, UNUSED_DATA)
{
gboolean success;
GError *error = NULL;
g_autofree char *tmppath = NULL;
int fd;
char buf[1024];

static const char* test_script = "r 100 Hello \n\
Expand All @@ -1852,17 +1850,10 @@ r 100 world\n";
"E: DEVNAME=/dev/greeter\nE: SUBSYSTEM=tty\nA: dev=4:64\n", &error);
g_assert_no_error(error);

/* write script into temporary file */
fd = g_file_open_tmp("test_script_simple.XXXXXX", &tmppath, &error);
g_assert_no_error(error);
g_assert_cmpint(write(fd, test_script, strlen(test_script)), >, 10);
close(fd);

/* load it */
success = umockdev_testbed_load_script(fixture->testbed, "/dev/greeter", tmppath, &error);
success = umockdev_testbed_load_script_from_string(fixture->testbed, "/dev/greeter", test_script, &error);
g_assert_no_error(error);
g_assert(success);
g_unlink (tmppath);

/* wait for it; this writes the output into the pipe buffer, and theoretically may block
* take the risk for the unit test, it's small enough */
Expand All @@ -1871,7 +1862,7 @@ r 100 world\n";
g_assert_no_error(error);

/* start communication */
fd = g_open("/dev/greeter", O_RDWR, 0);
int fd = g_open("/dev/greeter", O_RDWR, 0);
g_assert_cmpint(fd, >=, 0);

/* we get the full message in a single read */
Expand All @@ -1886,6 +1877,19 @@ r 100 world\n";
g_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_clear_error(&error);

/* can load a new script into the same device after waiting */
success = umockdev_testbed_load_script_from_string(fixture->testbed, "/dev/greeter", "r 50 Again\n", &error);
g_assert_no_error(error);
g_assert(success);
success = umockdev_testbed_wait_script(fixture->testbed, "/dev/greeter", &error);
g_assert(success);
g_assert_no_error(error);
fd = g_open("/dev/greeter", O_RDWR, 0);
g_assert_cmpint(fd, >=, 0);
g_assert_cmpint(read(fd, buf, sizeof buf), ==, 5);
g_assert_cmpint(memcmp(buf, "Again", 5), ==, 0);
close(fd);

/* invalid device */
success = umockdev_testbed_wait_script(fixture->testbed, "/dev/invalid", &error);
g_assert_false(success);
Expand Down Expand Up @@ -1964,8 +1968,6 @@ t_testbed_script_replay_fuzz(UMockdevTestbedFixture * fixture, UNUSED_DATA)
{
gboolean success;
GError *error = NULL;
g_autofree char *tmppath = NULL;
int fd;
char buf[1024];

static const char* test_script = "f 20 -\n\
Expand All @@ -1978,20 +1980,13 @@ r 0 OK\n";
"E: DEVNAME=/dev/fuzzy\nE: SUBSYSTEM=tty\nA: dev=4:64\n", &error);
g_assert_no_error(error);

/* write script into temporary file */
fd = g_file_open_tmp("test_script_fuzzy.XXXXXX", &tmppath, &error);
g_assert_no_error(error);
g_assert_cmpint(write(fd, test_script, strlen(test_script)), >, 10);
close(fd);

/* load it */
success = umockdev_testbed_load_script(fixture->testbed, "/dev/fuzzy", tmppath, &error);
success = umockdev_testbed_load_script_from_string(fixture->testbed, "/dev/fuzzy", test_script, &error);
g_assert_no_error(error);
g_assert(success);
g_unlink (tmppath);

/* start communication */
fd = g_open("/dev/fuzzy", O_RDWR | O_NONBLOCK, 0);
int fd = g_open("/dev/fuzzy", O_RDWR | O_NONBLOCK, 0);
g_assert_cmpint(fd, >=, 0);
errno = 0;

Expand Down

0 comments on commit 1243389

Please sign in to comment.