1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 13 авг. 2019 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #include <core/alloc.h> 23 #include <test/utest.h> 24 #include <core/ipc/Process.h> 25 #include <core/ipc/Thread.h> 26 #include <core/system.h> 27 28 using namespace lsp; 29 30 #define ENV_VAR_NAME "LSP_TEST_ENV_VAR" 31 32 UTEST_BEGIN("core.ipc", process) 33 UTEST_TIMELIMIT(10) 34 test_envs(ipc::Process & p)35 void test_envs(ipc::Process &p) 36 { 37 size_t envs = p.envs(); 38 UTEST_ASSERT(envs > 0); 39 LSPString key, value; 40 41 for (size_t i=0; i<envs; ++i) 42 { 43 UTEST_ASSERT(p.read_env(i, &key, &value) == STATUS_OK); 44 printf(" env: %s = %s\n", key.get_native(), value.get_native()); 45 } 46 47 UTEST_ASSERT(p.get_env(ENV_VAR_NAME, &value) == STATUS_NOT_FOUND); 48 UTEST_ASSERT(p.set_env(ENV_VAR_NAME, "123456") == STATUS_OK); 49 UTEST_ASSERT(envs == (p.envs() - 1)); 50 value.clear(); 51 UTEST_ASSERT(p.get_env(ENV_VAR_NAME, &value) == STATUS_OK); 52 printf("get_env(%s) = %s\n", ENV_VAR_NAME, value.get_native()); 53 UTEST_ASSERT(value.equals_ascii("123456")); 54 value.clear(); 55 UTEST_ASSERT(p.remove_env(ENV_VAR_NAME, &value) == STATUS_OK); 56 UTEST_ASSERT(value.equals_ascii("123456")); 57 UTEST_ASSERT(envs == p.envs()); 58 UTEST_ASSERT(p.clear_env() == STATUS_OK); 59 UTEST_ASSERT(p.envs() == 0); 60 UTEST_ASSERT(p.copy_env() == STATUS_OK); 61 UTEST_ASSERT(p.envs() == envs); 62 } 63 test_args(ipc::Process & p)64 void test_args(ipc::Process &p) 65 { 66 UTEST_ASSERT(p.args() == 0); 67 LSPString tmp; 68 char *ctmp = NULL; 69 70 UTEST_ASSERT(p.add_arg("arg1") == STATUS_OK); 71 UTEST_ASSERT(p.add_arg("arg4") == STATUS_OK); 72 UTEST_ASSERT(tmp.set_ascii("arg3")); 73 UTEST_ASSERT(p.add_arg(&tmp) == STATUS_OK); 74 UTEST_ASSERT(p.insert_arg(1, "arg2") == STATUS_OK); 75 UTEST_ASSERT(p.args() == 4); 76 UTEST_ASSERT(p.remove_arg(2, &tmp) == STATUS_OK); 77 UTEST_ASSERT(tmp.equals_ascii("arg4")); 78 UTEST_ASSERT(p.args() == 3); 79 80 UTEST_ASSERT(p.get_arg(0, &ctmp) == STATUS_OK); 81 UTEST_ASSERT(strcmp(ctmp, "arg1") == 0); 82 ::free(ctmp); 83 84 UTEST_ASSERT(p.get_arg(1, &ctmp) == STATUS_OK); 85 UTEST_ASSERT(strcmp(ctmp, "arg2") == 0); 86 ::free(ctmp); 87 88 tmp.clear(); 89 UTEST_ASSERT(p.get_arg(2, &tmp) == STATUS_OK); 90 UTEST_ASSERT(tmp.equals_ascii("arg3")); 91 92 UTEST_ASSERT(p.clear_args() == STATUS_OK); 93 UTEST_ASSERT(p.args() == 0); 94 } 95 96 UTEST_MAIN 97 { 98 if (argc <= 0) 99 { 100 ipc::Process p; 101 test_envs(p); 102 test_args(p); 103 104 LSPString cmd; 105 #ifdef PLATFORM_WINDOWS 106 UTEST_ASSERT(cmd.set_utf8(executable())); 107 #else 108 UTEST_ASSERT(cmd.set_native(executable())); 109 #endif 110 111 // Form the command line 112 p.set_command(&cmd); 113 p.add_arg("utest"); 114 p.add_arg("--debug"); 115 p.add_arg("--verbose"); 116 p.add_arg("--nofork"); 117 p.add_arg(full_name()); 118 p.add_arg("--args"); 119 p.add_arg("child"); 120 p.add_arg("arg1"); 121 p.add_arg("arg2"); 122 123 // Set environment 124 p.set_env(ENV_VAR_NAME, "test_value"); 125 126 // Redirect stdout and stderr 127 io::IInStream *xstdout = p.get_stdout(); 128 UTEST_ASSERT(xstdout != NULL); 129 io::IInStream *xstderr = p.get_stderr(); 130 UTEST_ASSERT(xstderr != NULL); 131 132 // Launch the process 133 printf("Starting child process...\n"); 134 UTEST_ASSERT(p.process_id() < 0); 135 UTEST_ASSERT(p.launch() == STATUS_OK); 136 printf("Started child process, pid=%d\n", int(p.process_id())); 137 UTEST_ASSERT(p.wait(0) == STATUS_OK); // Test process status 138 UTEST_ASSERT(p.wait(200) == STATUS_OK); // Wait for a short while 139 UTEST_ASSERT(p.status() == ipc::Process::PSTATUS_RUNNING); // Check status 140 printf("Waiting for process...\n"); 141 UTEST_ASSERT(p.wait() == STATUS_OK); // Wait until termination 142 143 // Close stdout and stderr 144 UTEST_ASSERT(xstdout->close() == STATUS_OK); 145 UTEST_ASSERT(xstderr->close() == STATUS_OK); 146 147 // Analyze exit status 148 int code = 0; 149 UTEST_ASSERT(p.exit_code(&code) == STATUS_OK); 150 printf("Waited process has terminated with code=%d\n", int(code)); 151 UTEST_ASSERT(code == 0); 152 153 printf("Parent process has exited\n"); 154 } 155 else 156 { 157 printf("Child process started\n"); 158 159 // Perform argument check 160 UTEST_ASSERT(argc == 3); 161 UTEST_ASSERT(strcmp(argv[0], "child") == 0); 162 UTEST_ASSERT(strcmp(argv[1], "arg1") == 0); 163 UTEST_ASSERT(strcmp(argv[2], "arg2") == 0); 164 165 LSPString value; 166 UTEST_ASSERT(system::get_env_var(ENV_VAR_NAME, &value) == STATUS_OK); 167 UTEST_ASSERT(value.equals_ascii("test_value")); 168 169 // Perform a sleep for synchronization with caller 170 printf("Entering sleep\n"); 171 ipc::Thread::sleep(2 * 1000); 172 printf("Child process has exited\n"); 173 } 174 } 175 UTEST_END; 176 177 178