[gnome-builder] libide/foundry: use PTY intercept when running tests
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide/foundry: use PTY intercept when running tests
- Date: Thu, 14 Jul 2022 23:47:48 +0000 (UTC)
commit 6c927fae51c056f2472604af69ff4d0b55575303
Author: Christian Hergert <chergert redhat com>
Date: Thu Jul 14 16:42:09 2022 -0700
libide/foundry: use PTY intercept when running tests
We will need this so that we can eventually parse unit test output for the
various kinds of providers (tap, etc). But furthermore, it actually allows
us to have multiple processes share a VtePty which is then rendered within
the testui VteTerminal widget.
Also make the IdeTest run_async() API private so that we can adjust it as
necessary. The public API is to run via the test-manager.
src/libide/foundry/ide-test-manager.c | 60 +++++++++++++++++++++++------------
src/libide/foundry/ide-test-private.h | 37 +++++++++++++++++++++
src/libide/foundry/ide-test.c | 21 ++++++++----
src/libide/foundry/ide-test.h | 11 -------
4 files changed, 91 insertions(+), 38 deletions(-)
---
diff --git a/src/libide/foundry/ide-test-manager.c b/src/libide/foundry/ide-test-manager.c
index 6fdd80117..a9501c27b 100644
--- a/src/libide/foundry/ide-test-manager.c
+++ b/src/libide/foundry/ide-test-manager.c
@@ -32,11 +32,12 @@
#include "ide-foundry-compat.h"
#include "ide-pipeline.h"
#include "ide-pty.h"
+#include "ide-run-context.h"
#include "ide-run-command.h"
#include "ide-run-commands.h"
#include "ide-run-manager.h"
-#include "ide-test.h"
#include "ide-test-manager.h"
+#include "ide-test-private.h"
#define MAX_UNIT_TESTS 4
@@ -59,6 +60,8 @@ struct _IdeTestManager
GtkFilterListModel *filtered;
IdeCachedListModel *tests;
VtePty *pty;
+ IdePtyIntercept intercept;
+ int pty_producer;
};
typedef struct
@@ -111,6 +114,7 @@ run_all_free (RunAll *state)
g_clear_pointer (&state->tests, g_ptr_array_unref);
g_clear_object (&state->pipeline);
g_clear_object (&state->pty);
+
g_slice_free (RunAll, state);
}
@@ -177,11 +181,17 @@ static void
ide_test_manager_dispose (GObject *object)
{
IdeTestManager *self = (IdeTestManager *)object;
+ g_auto(IdePtyFd) fd = IDE_PTY_FD_INVALID;
- g_clear_object (&self->pty);
g_clear_object (&self->filtered);
g_clear_object (&self->tests);
+ g_clear_object (&self->pty);
+ fd = pty_fd_steal (&self->pty_producer);
+
+ if (IDE_IS_PTY_INTERCEPT (&self->intercept))
+ ide_pty_intercept_clear (&self->intercept);
+
G_OBJECT_CLASS (ide_test_manager_parent_class)->dispose (object);
}
@@ -236,8 +246,16 @@ ide_test_manager_init (IdeTestManager *self)
{
GtkCustomFilter *filter;
GtkMapListModel *map;
+ int consumer_fd;
self->pty = ide_pty_new_sync (NULL);
+ self->pty_producer = -1;
+
+ /* Now create intercept, which we'll use to apply PTY
+ * to all the spawned processes instead of our VtePty.
+ */
+ consumer_fd = vte_pty_get_fd (self->pty);
+ ide_pty_intercept_init (&self->intercept, consumer_fd, NULL);
filter = gtk_custom_filter_new (filter_tests_func, NULL, NULL);
self->filtered = gtk_filter_list_model_new (NULL, GTK_FILTER (filter));
@@ -252,7 +270,7 @@ ide_test_manager_run_all_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- IdeTest *test = (IdeTest *)object;
+ IdeTestManager *self = (IdeTestManager *)object;
g_autoptr(IdeTask) task = user_data;
g_autoptr(GError) error = NULL;
GCancellable *cancellable;
@@ -261,7 +279,7 @@ ide_test_manager_run_all_cb (GObject *object,
IDE_ENTRY;
g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (IDE_IS_TEST (test));
+ g_assert (IDE_IS_TEST_MANAGER (self));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (IDE_IS_TASK (task));
@@ -270,10 +288,9 @@ ide_test_manager_run_all_cb (GObject *object,
g_assert (state != NULL);
g_assert (state->n_active > 0);
- g_assert (!state->pty || VTE_IS_PTY (state->pty));
g_assert (state->tests != NULL);
- if (!ide_test_run_finish (test, result, &error))
+ if (!ide_test_manager_run_finish (self, result, &error))
g_message ("%s", error->message);
if (state->tests->len > 0 &&
@@ -283,12 +300,11 @@ ide_test_manager_run_all_cb (GObject *object,
state->n_active++;
- ide_test_run_async (next_test,
- state->pipeline,
- state->pty,
- cancellable,
- ide_test_manager_run_all_cb,
- g_object_ref (task));
+ ide_test_manager_run_async (self,
+ next_test,
+ cancellable,
+ ide_test_manager_run_all_cb,
+ g_object_ref (task));
}
state->n_active--;
@@ -360,7 +376,6 @@ ide_test_manager_run_all_async (IdeTestManager *self,
state = g_slice_new0 (RunAll);
state->tests = g_ptr_array_ref (ar);
state->pipeline = g_object_ref (pipeline);
- state->pty = g_object_ref (self->pty);
state->n_active = 0;
ide_task_set_task_data (task, state, run_all_free);
@@ -370,12 +385,11 @@ ide_test_manager_run_all_async (IdeTestManager *self,
state->n_active++;
- ide_test_run_async (test,
- state->pipeline,
- state->pty,
- cancellable,
- ide_test_manager_run_all_cb,
- g_object_ref (task));
+ ide_test_manager_run_async (self,
+ test,
+ cancellable,
+ ide_test_manager_run_all_cb,
+ g_object_ref (task));
}
if (state->n_active == 0)
@@ -477,6 +491,12 @@ ide_test_manager_run_async (IdeTestManager *self,
build_manager = ide_build_manager_from_context (context);
pipeline = ide_build_manager_get_pipeline (build_manager);
+ if (self->pty_producer == -1)
+ {
+ IdePtyFd consumer_fd = ide_pty_intercept_get_fd (&self->intercept);
+ self->pty_producer = ide_pty_intercept_create_producer (consumer_fd, TRUE);
+ }
+
if (pipeline == NULL)
ide_task_return_new_error (task,
G_IO_ERROR,
@@ -485,7 +505,7 @@ ide_test_manager_run_async (IdeTestManager *self,
else
ide_test_run_async (test,
pipeline,
- self->pty,
+ self->pty_producer,
cancellable,
ide_test_manager_run_cb,
g_steal_pointer (&task));
diff --git a/src/libide/foundry/ide-test-private.h b/src/libide/foundry/ide-test-private.h
new file mode 100644
index 000000000..da7fc741a
--- /dev/null
+++ b/src/libide/foundry/ide-test-private.h
@@ -0,0 +1,37 @@
+/* ide-test-private.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ide-test.h"
+
+G_BEGIN_DECLS
+
+void ide_test_run_async (IdeTest *self,
+ IdePipeline *pipeline,
+ int pty_fd,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ide_test_run_finish (IdeTest *self,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
diff --git a/src/libide/foundry/ide-test.c b/src/libide/foundry/ide-test.c
index 55790ccc9..fd59facb7 100644
--- a/src/libide/foundry/ide-test.c
+++ b/src/libide/foundry/ide-test.c
@@ -22,15 +22,17 @@
#include "config.h"
+#include <unistd.h>
+
#include <libide-io.h>
#include <libide-threading.h>
-#include "ide-run-command.h"
-#include "ide-run-context.h"
#include "ide-foundry-enums.h"
#include "ide-pipeline.h"
+#include "ide-run-command.h"
+#include "ide-run-context.h"
#include "ide-runtime.h"
-#include "ide-test.h"
+#include "ide-test-private.h"
struct _IdeTest
{
@@ -284,7 +286,7 @@ ide_test_wait_check_cb (GObject *object,
void
ide_test_run_async (IdeTest *self,
IdePipeline *pipeline,
- VtePty *pty,
+ int pty_fd,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -302,7 +304,6 @@ ide_test_run_async (IdeTest *self,
g_return_if_fail (IDE_IS_TEST (self));
g_return_if_fail (IDE_IS_PIPELINE (pipeline));
- g_return_if_fail (!pty || VTE_IS_PTY (pty));
g_return_if_fail (IDE_IS_RUN_COMMAND (self->run_command));
task = ide_task_new (self, cancellable, callback, user_data);
@@ -327,8 +328,14 @@ ide_test_run_async (IdeTest *self,
run_context = ide_pipeline_create_run_context (pipeline, self->run_command);
}
- if (pty != NULL)
- ide_run_context_set_pty (run_context, pty);
+ if (pty_fd > -1)
+ {
+ ide_run_context_take_fd (run_context, dup (pty_fd), STDIN_FILENO);
+ ide_run_context_take_fd (run_context, dup (pty_fd), STDOUT_FILENO);
+ ide_run_context_take_fd (run_context, dup (pty_fd), STDERR_FILENO);
+
+ ide_run_context_setenv (run_context, "TERM", "xterm-256color");
+ }
if (!(subprocess = ide_run_context_spawn (run_context, &error)))
{
diff --git a/src/libide/foundry/ide-test.h b/src/libide/foundry/ide-test.h
index de4883ce1..22c60a97a 100644
--- a/src/libide/foundry/ide-test.h
+++ b/src/libide/foundry/ide-test.h
@@ -57,16 +57,5 @@ IDE_AVAILABLE_IN_ALL
const char *ide_test_get_icon_name (IdeTest *self);
IDE_AVAILABLE_IN_ALL
IdeRunCommand *ide_test_get_run_command (IdeTest *self);
-IDE_AVAILABLE_IN_ALL
-void ide_test_run_async (IdeTest *self,
- IdePipeline *pipeline,
- VtePty *pty,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_ALL
-gboolean ide_test_run_finish (IdeTest *self,
- GAsyncResult *result,
- GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]