mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
testing/libc/popen: add popen/dpopen test for shell and no-shell modes
Add tests for popen()/pclose() and dpopen()/dpclose() that work in both shell (NSH) and no-shell (direct posix_spawnp) modes. The test binary doubles as its own target via the --echo sub-command. Tests: 1-4: popen - basic read, multi-arg, pclose, invalid mode 5-7: dpopen - basic read, multi-arg, dpclose Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
This commit is contained in:
parent
5c654d5b8e
commit
00a219843c
5 changed files with 356 additions and 0 deletions
33
testing/libc/popen/CMakeLists.txt
Normal file
33
testing/libc/popen/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# ##############################################################################
|
||||
# apps/testing/libc/popen/CMakeLists.txt
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
# license agreements. See the NOTICE file distributed with this work for
|
||||
# additional information regarding copyright ownership. The ASF licenses this
|
||||
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy of
|
||||
# the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
if(CONFIG_TESTING_POPEN)
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
popen_test
|
||||
STACKSIZE
|
||||
${CONFIG_DEFAULT_TASK_STACKSIZE}
|
||||
MODULE
|
||||
${CONFIG_TESTING_POPEN}
|
||||
SRCS
|
||||
popen_test.c)
|
||||
endif()
|
||||
16
testing/libc/popen/Kconfig
Normal file
16
testing/libc/popen/Kconfig
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config TESTING_POPEN
|
||||
tristate "popen()/dpopen() test"
|
||||
default n
|
||||
depends on SYSTEM_POPEN
|
||||
---help---
|
||||
Test popen()/pclose() and dpopen()/dpclose() in both shell
|
||||
and no-shell modes. The test binary doubles as its own
|
||||
popen/dpopen target via --echo.
|
||||
|
||||
if TESTING_POPEN
|
||||
endif
|
||||
25
testing/libc/popen/Make.defs
Normal file
25
testing/libc/popen/Make.defs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
############################################################################
|
||||
# apps/testing/libc/popen/Make.defs
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifneq ($(CONFIG_TESTING_POPEN),)
|
||||
CONFIGURED_APPS += $(APPDIR)/testing/libc/popen
|
||||
endif
|
||||
32
testing/libc/popen/Makefile
Normal file
32
testing/libc/popen/Makefile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
############################################################################
|
||||
# apps/testing/libc/popen/Makefile
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
PROGNAME = popen_test
|
||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
|
||||
MODULE = $(CONFIG_TESTING_POPEN)
|
||||
|
||||
MAINSRC = popen_test.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
250
testing/libc/popen/popen_test.c
Normal file
250
testing/libc/popen/popen_test.c
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/libc/popen/popen_test.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int test_popen_read(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[256];
|
||||
int found = 0;
|
||||
|
||||
printf("[TEST 1] popen read...\n");
|
||||
fp = popen("popen_test --echo hello_popen", "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("[FAIL] popen returned NULL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL)
|
||||
{
|
||||
printf(" > %s", buf);
|
||||
if (strstr(buf, "hello_popen"))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
printf("%s\n", found ? "[PASS]" : "[FAIL] missing output");
|
||||
return !found;
|
||||
}
|
||||
|
||||
static int test_popen_multiarg(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[256];
|
||||
int found = 0;
|
||||
|
||||
printf("[TEST 2] popen multi-arg...\n");
|
||||
fp = popen("popen_test --echo aaa bbb ccc", "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("[FAIL] popen returned NULL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL)
|
||||
{
|
||||
printf(" > %s", buf);
|
||||
if (strstr(buf, "aaa bbb ccc"))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
printf("%s\n", found ? "[PASS]" : "[FAIL] wrong output");
|
||||
return !found;
|
||||
}
|
||||
|
||||
static int test_pclose_complete(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[256];
|
||||
|
||||
printf("[TEST 3] pclose completes...\n");
|
||||
fp = popen("popen_test --echo ok", "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("[FAIL] popen returned NULL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL);
|
||||
pclose(fp);
|
||||
printf("[PASS]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_popen_invalid_mode(void)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
printf("[TEST 4] popen invalid mode...\n");
|
||||
fp = popen("popen_test", "x");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("[PASS]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
printf("[FAIL] should return NULL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_dpopen_read(void)
|
||||
{
|
||||
char buf[256];
|
||||
ssize_t n;
|
||||
pid_t pid;
|
||||
int found = 0;
|
||||
int fd;
|
||||
|
||||
printf("[TEST 5] dpopen read...\n");
|
||||
fd = dpopen("popen_test --echo hello_dpopen", O_RDONLY, &pid);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("[FAIL] dpopen returned %d\n", fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((n = read(fd, buf, sizeof(buf) - 1)) > 0)
|
||||
{
|
||||
buf[n] = '\0';
|
||||
printf(" > %s", buf);
|
||||
if (strstr(buf, "hello_dpopen"))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
dpclose(fd, pid);
|
||||
printf("%s\n", found ? "[PASS]" : "[FAIL] missing output");
|
||||
return !found;
|
||||
}
|
||||
|
||||
static int test_dpopen_multiarg(void)
|
||||
{
|
||||
char buf[256];
|
||||
ssize_t n;
|
||||
pid_t pid;
|
||||
int found = 0;
|
||||
int fd;
|
||||
|
||||
printf("[TEST 6] dpopen multi-arg...\n");
|
||||
fd = dpopen("popen_test --echo xxx yyy zzz", O_RDONLY, &pid);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("[FAIL] dpopen returned %d\n", fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((n = read(fd, buf, sizeof(buf) - 1)) > 0)
|
||||
{
|
||||
buf[n] = '\0';
|
||||
printf(" > %s", buf);
|
||||
if (strstr(buf, "xxx yyy zzz"))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
dpclose(fd, pid);
|
||||
printf("%s\n", found ? "[PASS]" : "[FAIL] wrong output");
|
||||
return !found;
|
||||
}
|
||||
|
||||
static int test_dpclose_complete(void)
|
||||
{
|
||||
char buf[256];
|
||||
pid_t pid;
|
||||
int fd;
|
||||
|
||||
printf("[TEST 7] dpclose completes...\n");
|
||||
fd = dpopen("popen_test --echo ok", O_RDONLY, &pid);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("[FAIL] dpopen returned %d\n", fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (read(fd, buf, sizeof(buf)) > 0);
|
||||
dpclose(fd, pid);
|
||||
printf("[PASS]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
int fail = 0;
|
||||
|
||||
/* Sub-command: echo args back, used as popen/dpopen target */
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "--echo") == 0)
|
||||
{
|
||||
int i;
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
printf("%s%s", i > 2 ? " " : "", argv[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("=== popen/dpopen test ===\n\n");
|
||||
|
||||
/* popen tests */
|
||||
|
||||
fail += test_popen_read();
|
||||
fail += test_popen_multiarg();
|
||||
fail += test_pclose_complete();
|
||||
fail += test_popen_invalid_mode();
|
||||
|
||||
/* dpopen tests */
|
||||
|
||||
fail += test_dpopen_read();
|
||||
fail += test_dpopen_multiarg();
|
||||
fail += test_dpclose_complete();
|
||||
|
||||
printf("\n=== Results: %d failed ===\n", fail);
|
||||
return fail;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue