aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorAndrea Corallo2020-03-29 12:31:24 +0100
committerAndrea Corallo2020-03-29 12:31:24 +0100
commit00ee320a620704ae12a1e2104c2d08bf8bbdf0c9 (patch)
tree498c59219b572c89e10f9521b54c98896cb52ca9 /test
parent530faee2752c7b316fa21f2ac4d1266d3e7a38e6 (diff)
parent76b3bd8cbb9a0a01941d9c1766c054960e4bfd97 (diff)
downloademacs-00ee320a620704ae12a1e2104c2d08bf8bbdf0c9.tar.gz
emacs-00ee320a620704ae12a1e2104c2d08bf8bbdf0c9.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'test')
-rw-r--r--test/data/emacs-module/mod-test.c93
-rw-r--r--test/lisp/image/gravatar-tests.el2
-rw-r--r--test/src/emacs-module-tests.el17
3 files changed, 108 insertions, 4 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c
index ec6948921f2..5e3112f4471 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -30,6 +30,19 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
30#include <string.h> 30#include <string.h>
31#include <time.h> 31#include <time.h>
32 32
33#ifdef WINDOWSNT
34/* Cannot include <process.h> because of the local header by the same
35 name, sigh. */
36uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, void *);
37# if !defined __x86_64__
38# define ALIGN_STACK __attribute__((force_align_arg_pointer))
39# endif
40# include <windows.h> /* for Sleep */
41#else /* !WINDOWSNT */
42# include <pthread.h>
43# include <unistd.h>
44#endif
45
33#ifdef HAVE_GMP 46#ifdef HAVE_GMP
34#include <gmp.h> 47#include <gmp.h>
35#else 48#else
@@ -299,7 +312,7 @@ Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
299} 312}
300 313
301/* An invalid finalizer: Finalizers are run during garbage collection, 314/* An invalid finalizer: Finalizers are run during garbage collection,
302 where Lisp code cant be executed. -module-assertions tests for 315 where Lisp code can't be executed. -module-assertions tests for
303 this case. */ 316 this case. */
304 317
305static emacs_env *current_env; 318static emacs_env *current_env;
@@ -320,9 +333,9 @@ Fmod_test_invalid_finalizer (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
320} 333}
321 334
322static void 335static void
323signal_errno (emacs_env *env, const char *function) 336signal_system_error (emacs_env *env, int error, const char *function)
324{ 337{
325 const char *message = strerror (errno); 338 const char *message = strerror (error);
326 emacs_value message_value = env->make_string (env, message, strlen (message)); 339 emacs_value message_value = env->make_string (env, message, strlen (message));
327 emacs_value symbol = env->intern (env, "file-error"); 340 emacs_value symbol = env->intern (env, "file-error");
328 emacs_value elements[2] 341 emacs_value elements[2]
@@ -331,6 +344,12 @@ signal_errno (emacs_env *env, const char *function)
331 env->non_local_exit_signal (env, symbol, data); 344 env->non_local_exit_signal (env, symbol, data);
332} 345}
333 346
347static void
348signal_errno (emacs_env *env, const char *function)
349{
350 signal_system_error (env, errno, function);
351}
352
334/* A long-running operation that occasionally calls `should_quit' or 353/* A long-running operation that occasionally calls `should_quit' or
335 `process_input'. */ 354 `process_input'. */
336 355
@@ -533,6 +552,73 @@ Fmod_test_function_finalizer_calls (emacs_env *env, ptrdiff_t nargs,
533 return env->funcall (env, Flist, 2, list_args); 552 return env->funcall (env, Flist, 2, list_args);
534} 553}
535 554
555static void
556sleep_for_half_second (void)
557{
558 /* mingw.org's MinGW has nanosleep, but MinGW64 doesn't. */
559#ifdef WINDOWSNT
560 Sleep (500);
561#else
562 const struct timespec sleep = {0, 500000000};
563 if (nanosleep (&sleep, NULL) != 0)
564 perror ("nanosleep");
565#endif
566}
567
568#ifdef WINDOWSNT
569static void ALIGN_STACK
570#else
571static void *
572#endif
573write_to_pipe (void *arg)
574{
575 /* We sleep a bit to test that writing to a pipe is indeed possible
576 if no environment is active. */
577 sleep_for_half_second ();
578 FILE *stream = arg;
579 /* The string below should be identical to the one we compare with
580 in emacs-module-tests.el:module/async-pipe. */
581 if (fputs ("data from thread", stream) < 0)
582 perror ("fputs");
583 if (fclose (stream) != 0)
584 perror ("close");
585#ifndef WINDOWSNT
586 return NULL;
587#endif
588}
589
590static emacs_value
591Fmod_test_async_pipe (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
592 void *data)
593{
594 assert (nargs == 1);
595 int fd = env->open_channel (env, args[0]);
596 if (env->non_local_exit_check (env) != emacs_funcall_exit_return)
597 return NULL;
598 FILE *stream = fdopen (fd, "w");
599 if (stream == NULL)
600 {
601 signal_errno (env, "fdopen");
602 return NULL;
603 }
604#ifdef WINDOWSNT
605 uintptr_t thd = _beginthread (write_to_pipe, 0, stream);
606 int error = (thd == (uintptr_t)-1L) ? errno : 0;
607#else /* !WINDOWSNT */
608 pthread_t thread;
609 int error
610 = pthread_create (&thread, NULL, write_to_pipe, stream);
611#endif
612 if (error != 0)
613 {
614 signal_system_error (env, error, "thread create");
615 if (fclose (stream) != 0)
616 perror ("fclose");
617 return NULL;
618 }
619 return env->intern (env, "nil");
620}
621
536/* Lisp utilities for easier readability (simple wrappers). */ 622/* Lisp utilities for easier readability (simple wrappers). */
537 623
538/* Provide FEATURE to Emacs. */ 624/* Provide FEATURE to Emacs. */
@@ -614,6 +700,7 @@ emacs_module_init (struct emacs_runtime *ert)
614 Fmod_test_make_function_with_finalizer, 0, 0, NULL, NULL); 700 Fmod_test_make_function_with_finalizer, 0, 0, NULL, NULL);
615 DEFUN ("mod-test-function-finalizer-calls", 701 DEFUN ("mod-test-function-finalizer-calls",
616 Fmod_test_function_finalizer_calls, 0, 0, NULL, NULL); 702 Fmod_test_function_finalizer_calls, 0, 0, NULL, NULL);
703 DEFUN ("mod-test-async-pipe", Fmod_test_async_pipe, 1, 1, NULL, NULL);
617 704
618#undef DEFUN 705#undef DEFUN
619 706
diff --git a/test/lisp/image/gravatar-tests.el b/test/lisp/image/gravatar-tests.el
index e66b5c6803d..66098fa0116 100644
--- a/test/lisp/image/gravatar-tests.el
+++ b/test/lisp/image/gravatar-tests.el
@@ -67,6 +67,6 @@
67 (gravatar-force-default nil) 67 (gravatar-force-default nil)
68 (gravatar-size nil)) 68 (gravatar-size nil))
69 (should (equal (gravatar-build-url "foo") "\ 69 (should (equal (gravatar-build-url "foo") "\
70https://www.gravatar.com/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g")))) 70https://seccdn.libravatar.org/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g"))))
71 71
72;;; gravatar-tests.el ends here 72;;; gravatar-tests.el ends here
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 48d2e86a605..6851b890451 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -424,4 +424,21 @@ See Bug#36226."
424 ;; but at least one. 424 ;; but at least one.
425 (should (> valid-after valid-before))))) 425 (should (> valid-after valid-before)))))
426 426
427(ert-deftest module/async-pipe ()
428 "Check that writing data from another thread works."
429 (skip-unless (not (eq system-type 'windows-nt))) ; FIXME!
430 (with-temp-buffer
431 (let ((process (make-pipe-process :name "module/async-pipe"
432 :buffer (current-buffer)
433 :coding 'utf-8-unix
434 :noquery t)))
435 (unwind-protect
436 (progn
437 (mod-test-async-pipe process)
438 (should (accept-process-output process 1))
439 ;; The string below must be identical to what
440 ;; mod-test.c:write_to_pipe produces.
441 (should (equal (buffer-string) "data from thread")))
442 (delete-process process)))))
443
427;;; emacs-module-tests.el ends here 444;;; emacs-module-tests.el ends here