[test] Add test for SHM
This commit is contained in:
		
							parent
							
								
									ed96ce55dd
								
							
						
					
					
						commit
						78450e58f8
					
				| @ -22,7 +22,7 @@ TESTS ?= env empty hello_world malloc mmap file fs_perms getpid spawn sched pipe | |||||||
| 	truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info rlimit \
 | 	truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info rlimit \
 | ||||||
| 	server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group posix_flock \
 | 	server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group posix_flock \
 | ||||||
| 	ioctl fcntl eventfd emulate_syscall access signal sysinfo prctl rename procfs wait \
 | 	ioctl fcntl eventfd emulate_syscall access signal sysinfo prctl rename procfs wait \
 | ||||||
| 	spawn_attribute exec statfs random umask pgrp vfork mount flock utimes | 	spawn_attribute exec statfs random umask pgrp vfork mount flock utimes shm | ||||||
| # Benchmarks: need to be compiled and run by bench-% target
 | # Benchmarks: need to be compiled and run by bench-% target
 | ||||||
| BENCHES := spawn_and_exit_latency pipe_throughput unix_socket_throughput | BENCHES := spawn_and_exit_latency pipe_throughput unix_socket_throughput | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								test/shm/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								test/shm/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | include ../test_common.mk | ||||||
|  | 
 | ||||||
|  | EXTRA_C_FLAGS := | ||||||
|  | EXTRA_LINK_FLAGS := | ||||||
|  | BIN_ARGS := | ||||||
							
								
								
									
										414
									
								
								test/shm/main.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										414
									
								
								test/shm/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,414 @@ | |||||||
|  | #define _GNU_SOURCE | ||||||
|  | #include <sys/ipc.h> | ||||||
|  | #include <sys/shm.h> | ||||||
|  | #include <sys/syscall.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/wait.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <spawn.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include "test.h" | ||||||
|  | 
 | ||||||
|  | // ============================================================================
 | ||||||
|  | // Global definitions
 | ||||||
|  | // ============================================================================
 | ||||||
|  | 
 | ||||||
|  | #define S_IRWUSER   (S_IRUSR | S_IWUSR) | ||||||
|  | 
 | ||||||
|  | #define TEST_GET_SHMID_BY_KEY   0 | ||||||
|  | #define TEST_PROCESS_COMMU      1 | ||||||
|  | #define TEST_OPERATE_DESTOYED   2 | ||||||
|  | 
 | ||||||
|  | #define TEST_GET_SHMID_BY_KEY_ARGC  5 | ||||||
|  | #define TEST_PROCESS_COMMU_ARGC     4 | ||||||
|  | #define TEST_OPERATE_DESTOYED_ARGC  5 | ||||||
|  | 
 | ||||||
|  | #define ARG_BUF_SZ  64 | ||||||
|  | #define PAGE_SIZE   (0x1000) | ||||||
|  | 
 | ||||||
|  | #define SUCCESS     1 | ||||||
|  | #define FAIL        (-1) | ||||||
|  | 
 | ||||||
|  | const char prog_name[] = "/bin/shm"; | ||||||
|  | 
 | ||||||
|  | // ============================================================================
 | ||||||
|  | // Helper macro and function
 | ||||||
|  | // ============================================================================
 | ||||||
|  | #define INFO(fmt, ...)   do { \ | ||||||
|  |     printf("\t\t[file: %s, line: %d, func: %s] " fmt, \ | ||||||
|  |     __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | // Spawn child, and check the return value from child
 | ||||||
|  | // Return `SUCCESS` if the execution succeeds,
 | ||||||
|  | // return `FAIL` if fails
 | ||||||
|  | static int execute_in_child(char **const child_argv) { | ||||||
|  |     int ret; | ||||||
|  |     pid_t child_pid; | ||||||
|  |     int child_status; | ||||||
|  | 
 | ||||||
|  |     ret = posix_spawn(&child_pid, prog_name, NULL, NULL, (char **const)child_argv, NULL); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("Failed to spawn a child process"); | ||||||
|  |     } | ||||||
|  |     ret = waitpid(child_pid, &child_status, 0); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("Failed to waitpid() for child process"); | ||||||
|  |     } | ||||||
|  |     if (!WIFEXITED(child_status) || WEXITSTATUS(child_status) != 0) { | ||||||
|  |         INFO("The test in child failed\n"); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ============================================================================
 | ||||||
|  | // Test cases for shm
 | ||||||
|  | // ============================================================================
 | ||||||
|  | static int test_shmget_shmid_from_key(void) { | ||||||
|  |     int ret, shmid; | ||||||
|  |     key_t key; | ||||||
|  |     size_t shm_size = PAGE_SIZE; | ||||||
|  |     char *child_argv[TEST_GET_SHMID_BY_KEY_ARGC + 1]; | ||||||
|  | 
 | ||||||
|  |     srand(time(NULL)); | ||||||
|  |     key = random(); | ||||||
|  |     // Get a non-existent shm segment, should get the return value with ENOENT
 | ||||||
|  |     ret = syscall(SYS_shmget, key, shm_size, S_IRWUSER); | ||||||
|  |     if (ret != -1 || errno != ENOENT) { | ||||||
|  |         INFO("shmget() should return ENOENT because the segment does not exist, ret: %d errno: %d\n", | ||||||
|  |              ret, errno); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Create a new shm segment
 | ||||||
|  |     shmid = syscall(SYS_shmget, key, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (shmid < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot create the shm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Get the shmid by key in the same process
 | ||||||
|  |     ret = syscall(SYS_shmget, key, shm_size, S_IRWUSER); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  |     if (ret != shmid) { | ||||||
|  |         INFO("shmid mismatches, correct: %d actual: %d\n", shmid, ret); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Create a shm segment whose key is already attached to existed segment,
 | ||||||
|  |     // should get the return value with EEXIST
 | ||||||
|  |     ret = syscall(SYS_shmget, key, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (ret != -1 || errno != EEXIST) { | ||||||
|  |         INFO("shmget() should return EEXIST because the segment already exists, ret: %d errno: %d\n", | ||||||
|  |              ret, errno); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Spawn a new process
 | ||||||
|  |     for (int i = 0; i < TEST_GET_SHMID_BY_KEY_ARGC; i++) { | ||||||
|  |         child_argv[i] = (char *)malloc(ARG_BUF_SZ); | ||||||
|  |     } | ||||||
|  |     snprintf(child_argv[0], ARG_BUF_SZ, "%s", prog_name); | ||||||
|  |     snprintf(child_argv[1], ARG_BUF_SZ, "%d", TEST_GET_SHMID_BY_KEY); | ||||||
|  |     snprintf(child_argv[2], ARG_BUF_SZ, "%d", key); | ||||||
|  |     snprintf(child_argv[3], ARG_BUF_SZ, "%d", shmid); | ||||||
|  |     snprintf(child_argv[4], ARG_BUF_SZ, "%ld", shm_size); | ||||||
|  |     child_argv[TEST_GET_SHMID_BY_KEY_ARGC] = NULL; | ||||||
|  |     if ((ret = execute_in_child(child_argv)) != SUCCESS) { | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     for (int i = 0; i < TEST_GET_SHMID_BY_KEY_ARGC; i++) { | ||||||
|  |         free(child_argv[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_RMID, NULL); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("Cannot remove the segment"); | ||||||
|  |     } | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int test_process_communication() { | ||||||
|  |     int shmid, ret; | ||||||
|  |     size_t shm_size = PAGE_SIZE; | ||||||
|  |     long random_num, *shm_addr; | ||||||
|  |     char *child_argv[TEST_PROCESS_COMMU_ARGC + 1]; | ||||||
|  | 
 | ||||||
|  |     shmid = syscall(SYS_shmget, IPC_PRIVATE, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (shmid < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  |     shm_addr = (long *)syscall(SYS_shmat, shmid, NULL, 0); | ||||||
|  |     if (shm_addr == (long *) -1) { | ||||||
|  |         THROW_ERROR("shmat() cannot attach the shm"); | ||||||
|  |     } | ||||||
|  |     srandom(time(NULL)); | ||||||
|  |     random_num = random(); | ||||||
|  |     *shm_addr = random_num; | ||||||
|  | 
 | ||||||
|  |     // Spawn a new process
 | ||||||
|  |     for (int i = 0; i < TEST_PROCESS_COMMU_ARGC; i++) { | ||||||
|  |         child_argv[i] = (char *)malloc(ARG_BUF_SZ); | ||||||
|  |     } | ||||||
|  |     snprintf(child_argv[0], ARG_BUF_SZ, "%s", prog_name); | ||||||
|  |     snprintf(child_argv[1], ARG_BUF_SZ, "%d", TEST_PROCESS_COMMU); | ||||||
|  |     snprintf(child_argv[2], ARG_BUF_SZ, "%d", shmid); | ||||||
|  |     snprintf(child_argv[3], ARG_BUF_SZ, "%ld", random_num); | ||||||
|  |     child_argv[TEST_PROCESS_COMMU_ARGC] = NULL; | ||||||
|  |     if ((ret = execute_in_child(child_argv)) != SUCCESS) { | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     for (int i = 0; i < TEST_PROCESS_COMMU_ARGC; i++) { | ||||||
|  |         free(child_argv[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmdt, (void *)shm_addr); | ||||||
|  |     if (ret != 0) { | ||||||
|  |         THROW_ERROR("shmdt() failed"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_RMID, NULL); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("Cannot remove the segment"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int test_immediately_rmshm() { | ||||||
|  |     int ret, shmid; | ||||||
|  |     size_t shm_size = PAGE_SIZE; | ||||||
|  |     struct shmid_ds buf; | ||||||
|  | 
 | ||||||
|  |     shmid = syscall(SYS_shmget, IPC_PRIVATE, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (shmid < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_RMID, NULL); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("Cannot remove the segment"); | ||||||
|  |     } | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_STAT, NULL); | ||||||
|  |     if (ret != -1 || errno != EINVAL) { | ||||||
|  |         INFO("Should get errno with EINVAL even though the buf is empty, ret: %d errno: %d\n", | ||||||
|  |              ret, errno); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_STAT, &buf); | ||||||
|  |     if (ret != -1 || errno != EINVAL) { | ||||||
|  |         INFO("The shared memory segment should be removed immediately since shm_nattach equals to 0, ret: %d errno: %d\n", | ||||||
|  |              ret, errno); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int test_operate_destroyed_shm() { | ||||||
|  |     int shmid, ret; | ||||||
|  |     size_t shm_size = PAGE_SIZE; | ||||||
|  |     void *shm_addr; | ||||||
|  |     key_t key; | ||||||
|  |     char *child_argv[TEST_OPERATE_DESTOYED_ARGC + 1]; | ||||||
|  | 
 | ||||||
|  |     srand(time(NULL)); | ||||||
|  |     key = random(); | ||||||
|  |     shmid = syscall(SYS_shmget, key, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (shmid < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  |     shm_addr = (void *)syscall(SYS_shmat, shmid, NULL, 0); | ||||||
|  |     if (shm_addr == (void *) -1) { | ||||||
|  |         THROW_ERROR("shmat() cannot attach the shm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Mark the shared memory segment to be destroyed first
 | ||||||
|  |     ret = syscall(SYS_shmctl, shmid, IPC_RMID, NULL); | ||||||
|  | 
 | ||||||
|  |     // Spawn a new process
 | ||||||
|  |     for (int i = 0; i < TEST_OPERATE_DESTOYED_ARGC; i++) { | ||||||
|  |         child_argv[i] = (char *)malloc(ARG_BUF_SZ); | ||||||
|  |     } | ||||||
|  |     snprintf(child_argv[0], ARG_BUF_SZ, "%s", prog_name); | ||||||
|  |     snprintf(child_argv[1], ARG_BUF_SZ, "%d", TEST_OPERATE_DESTOYED); | ||||||
|  |     snprintf(child_argv[2], ARG_BUF_SZ, "%d", key); | ||||||
|  |     snprintf(child_argv[3], ARG_BUF_SZ, "%ld", shm_size); | ||||||
|  |     snprintf(child_argv[4], ARG_BUF_SZ, "%d", shmid); | ||||||
|  |     child_argv[TEST_OPERATE_DESTOYED_ARGC] = NULL; | ||||||
|  |     if ((ret = execute_in_child(child_argv)) != SUCCESS) { | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     for (int i = 0; i < TEST_OPERATE_DESTOYED_ARGC; i++) { | ||||||
|  |         free(child_argv[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmdt, shm_addr); | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // test_no_rmshm() should be place as the last test case
 | ||||||
|  | //
 | ||||||
|  | // Occlum checks whether all the memory segment is recycled when the LibOS exits,
 | ||||||
|  | // to detect and prevent memory leaks.
 | ||||||
|  | // Such test checks whether all the vmas allocated by `shm mod` are recycled when the LibOS exits,
 | ||||||
|  | // even though no IPC_RMID is invoked for the shared memory segment.
 | ||||||
|  | static int test_no_rmshm() { | ||||||
|  |     int shmid; | ||||||
|  |     size_t shm_size = PAGE_SIZE; | ||||||
|  |     void *shm_addr; | ||||||
|  | 
 | ||||||
|  |     shmid = syscall(SYS_shmget, IPC_PRIVATE, shm_size, IPC_CREAT | IPC_EXCL | S_IRWUSER); | ||||||
|  |     if (shmid < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  |     shm_addr = (void *)syscall(SYS_shmat, shmid, NULL, 0); | ||||||
|  |     if (shm_addr == (long *) -1) { | ||||||
|  |         THROW_ERROR("shmat() cannot attach the shm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ============================================================================
 | ||||||
|  | // Funtion invoked in child process for inter-process communication
 | ||||||
|  | // ============================================================================
 | ||||||
|  | 
 | ||||||
|  | static int child_test_get_shmid_by_key(int argc, const char *argv[]) { | ||||||
|  |     key_t key; | ||||||
|  |     int ret, shmid; | ||||||
|  |     size_t shm_size; | ||||||
|  | 
 | ||||||
|  |     if (argc != TEST_GET_SHMID_BY_KEY_ARGC) { | ||||||
|  |         INFO("Invalid argument, argc: %d\n", argc); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     key = atoi(argv[2]); | ||||||
|  |     shmid = atoi(argv[3]); | ||||||
|  |     shm_size = atol(argv[4]); | ||||||
|  | 
 | ||||||
|  |     // Get the shmid by the key input from parent process
 | ||||||
|  |     ret = syscall(SYS_shmget, key, shm_size, S_IRWUSER); | ||||||
|  |     if (ret < 0) { | ||||||
|  |         THROW_ERROR("shmget() cannot get the shm"); | ||||||
|  |     } | ||||||
|  |     if (ret != shmid) { | ||||||
|  |         INFO("shmid get in child process mismatches that in parent process, correct: %d actual: %d\n", | ||||||
|  |              shmid, key); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int child_test_process_communication(int argc, const char *argv[]) { | ||||||
|  |     int shmid, ret; | ||||||
|  |     long random_num, *shm_ptr; | ||||||
|  | 
 | ||||||
|  |     if (argc != TEST_PROCESS_COMMU_ARGC) { | ||||||
|  |         INFO("Invalid argument, argc: %d\n", argc); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     shmid = atoi(argv[2]); | ||||||
|  |     random_num = atol(argv[3]); | ||||||
|  | 
 | ||||||
|  |     // Check whether the value in the shared memory segment equals to
 | ||||||
|  |     // that written in parent process
 | ||||||
|  |     shm_ptr = (long *)syscall(SYS_shmat, shmid, NULL, 0); | ||||||
|  |     if (shm_ptr == (long *) -1) { | ||||||
|  |         THROW_ERROR("shmat() cannot attach to the shm"); | ||||||
|  |     } | ||||||
|  |     if (*shm_ptr != random_num) { | ||||||
|  |         INFO("Data in shm mismatches, correct: %ld actual: %ld\n", random_num, *shm_ptr); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmdt, (void *)shm_ptr); | ||||||
|  |     if (ret != 0) { | ||||||
|  |         THROW_ERROR("shmdt() failed"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int child_test_operate_destroyed_shm(int argc, const char *argv[]) { | ||||||
|  |     int shmid, ret; | ||||||
|  |     key_t key; | ||||||
|  |     size_t shm_size; | ||||||
|  |     void *shm_addr; | ||||||
|  | 
 | ||||||
|  |     if (argc != TEST_OPERATE_DESTOYED_ARGC) { | ||||||
|  |         INFO("Invalid argument, argc: %d\n", argc); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  |     key = atoi(argv[2]); | ||||||
|  |     shm_size = atol(argv[3]); | ||||||
|  |     shmid = atoi(argv[4]); | ||||||
|  | 
 | ||||||
|  |     ret = syscall(SYS_shmget, key, shm_size, S_IRWUSER); | ||||||
|  |     if (ret != -1 || errno != ENOENT) { | ||||||
|  |         INFO("shmget() should return ENOENT because the segment is marked to be destoyed, ret: %d errno: %d\n", | ||||||
|  |              ret, errno); | ||||||
|  |         return FAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     shm_addr = (void *)syscall(SYS_shmat, shmid, NULL, 0); | ||||||
|  |     if (shm_addr == (void *) -1) { | ||||||
|  |         THROW_ERROR("shmat() cannot attach the shm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((ret = syscall(SYS_shmdt, shm_addr)) != 0) { | ||||||
|  |         THROW_ERROR("shmdt() failed"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ============================================================================
 | ||||||
|  | // Test suite main
 | ||||||
|  | // ============================================================================
 | ||||||
|  | 
 | ||||||
|  | static test_case_t test_cases[] = { | ||||||
|  |     TEST_CASE(test_shmget_shmid_from_key), | ||||||
|  |     TEST_CASE(test_process_communication), | ||||||
|  |     TEST_CASE(test_immediately_rmshm), | ||||||
|  |     TEST_CASE(test_operate_destroyed_shm), | ||||||
|  |     // test_no_rmshm() should be place as the last test case
 | ||||||
|  |     TEST_CASE(test_no_rmshm), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int main(int argc, const char *argv[]) { | ||||||
|  |     if (argc == 1) { | ||||||
|  |         // Parent process will arrive here
 | ||||||
|  |         return test_suite_run(test_cases, ARRAY_SIZE(test_cases)); | ||||||
|  |     } else { | ||||||
|  |         // Child process will arrive here
 | ||||||
|  |         int option = atoi(argv[1]), ret; | ||||||
|  |         switch (option) { | ||||||
|  |             case TEST_GET_SHMID_BY_KEY: | ||||||
|  |                 ret = child_test_get_shmid_by_key(argc, argv); | ||||||
|  |                 break; | ||||||
|  |             case TEST_PROCESS_COMMU: | ||||||
|  |                 ret = child_test_process_communication(argc, argv); | ||||||
|  |                 break; | ||||||
|  |             case TEST_OPERATE_DESTOYED: | ||||||
|  |                 ret = child_test_operate_destroyed_shm(argc, argv); | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 INFO("Invalid option: %d\n", option); | ||||||
|  |                 ret = FAIL; | ||||||
|  |         } | ||||||
|  |         if (ret == SUCCESS) { | ||||||
|  |             return 0; | ||||||
|  |         } else { | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user