From: Kunhoon Baik Date: Mon, 19 Jul 2021 04:27:18 +0000 (+0900) Subject: Add nsjail test Tizen application X-Git-Tag: submit/tizen/20210825.085400~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6c9976a39009ec8ca877053e67ff7a8a275b4f5;p=platform%2Fupstream%2Fnsjail.git Add nsjail test Tizen application This is an application to execute nsjail for testing nsjail in Tizen application Environment. Use build script "build_test_runner.sh" to build. You need to install Tizen CLI to build. You can execute the app like following. - $> aul_test launch test_runner execute /usr/bin/nsjail_test/jail_mem_syscall_test --- diff --git a/test/test_runner_app/Jenkinsfile b/test/test_runner_app/Jenkinsfile new file mode 100644 index 0000000..0d35d61 --- /dev/null +++ b/test/test_runner_app/Jenkinsfile @@ -0,0 +1,121 @@ +pipeline { + agent none + options { buildDiscarder(logRotator(artifactNumToKeepStr: "10")) } + stages { + stage("Build") { + parallel { + stage("Debug") { + agent { label "ses-latest" } + environment { + ARCH = "arm" + BUILD_TYPE = "Debug" + } + steps { + script { + sh """ + wget --no-cache https://github.sec.samsung.net/pages/SES/Tools/bin/ses-build.py + chmod +x ./ses-build.py + ./ses-build.py -f -i /home/developer/bin + """ + } + script { + sh "./ses-build.py -f -r ${BUILD_TYPE}" + } + } + post { + always { + archiveArtifacts artifacts: "artifacts/**", fingerprint: true + cleanWs deleteDirs: true + dir("${env.WORKSPACE}@tmp") { + deleteDir() + } + dir("${env.WORKSPACE}@libs") { + deleteDir() + } + dir("${env.WORKSPACE}@script") { + deleteDir() + } + dir("${env.WORKSPACE}@script@tmp") { + deleteDir() + } + } + } + } + stage("Release") { + agent { label "ses-latest" } + environment { + ARCH = "arm" + BUILD_TYPE = "Release" + } + steps { + script { + sh """ + wget --no-cache https://github.sec.samsung.net/pages/SES/Tools/bin/ses-build.py + chmod +x ./ses-build.py + ./ses-build.py -f -i /home/developer/bin + """ + } + script { + sh "./ses-build.py -f -r ${BUILD_TYPE}" + } + } + post { + always { + archiveArtifacts artifacts: "artifacts/**", fingerprint: true + cleanWs deleteDirs: true + dir("${env.WORKSPACE}@tmp") { + deleteDir() + } + dir("${env.WORKSPACE}@libs") { + deleteDir() + } + dir("${env.WORKSPACE}@script") { + deleteDir() + } + dir("${env.WORKSPACE}@script@tmp") { + deleteDir() + } + } + } + } + } + } + stage("Sign") { + agent any + steps { + script { + DOWNSTREAM_JOB = build job: "mde-enabler-signer/master", parameters: [ booleanParam(name: 'DO_KUEP_SIGN', value: true) ] + DOWNSTREAM_BUILD_NUM = DOWNSTREAM_JOB.getNumber().toString() + } + } + post { + always { + step([ + $class: "CopyArtifact", + filter: "artifacts/**/*.tpk", + projectName: "mde-enabler-signer/master", + selector: [ + $class: "SpecificBuildSelector", + buildNumber: DOWNSTREAM_BUILD_NUM + ] + ]) + archiveArtifacts artifacts: "artifacts/**", fingerprint: true + cleanWs deleteDirs: true + dir("${env.WORKSPACE}@tmp") { + deleteDir() + } + dir("${env.WORKSPACE}@libs") { + deleteDir() + } + dir("${env.WORKSPACE}@script") { + deleteDir() + } + dir("${env.WORKSPACE}@script@tmp") { + deleteDir() + } + } + } + } + } +} + diff --git a/test/test_runner_app/build_test_runner.sh b/test/test_runner_app/build_test_runner.sh new file mode 100755 index 0000000..34b0cb0 --- /dev/null +++ b/test/test_runner_app/build_test_runner.sh @@ -0,0 +1,124 @@ +#!/bin/bash -e +# + +BIN_ROOT=test_runner + +ARCH=${1} +REL=${2} +RS_VER=${3} +RS=${4} + +if [ -z "${ARCH}" ] +then + ARCH="arm" +fi + +if [ -z "${REL}" ] +then + REL="Debug" +fi + +if [ -z "${RS_VER}" ] +then + RS_VER="6.0" +fi + +if [ -z "${RS}" ] +then + RS="mde-6.0-device.core.public" +fi + +PrjList=( + ${BIN_ROOT} +) + +Usage() { + echo "usage)./build_test_runner.sh {arm|x86} {Debug|Release} {rootstrap_version} {rootstrap_name}" + exit +} + +Clean() { + if [ "z$1" = "z" ]; then + echo "Missing build directory" + exit + fi + + if [ -e $1"/"${REL} ]; then + rm -r $1"/"${REL} + fi +} + +CleanAll() { + for it in ${PrjList[@]} + do + Clean $it + done +} + +Build() { + if [ "z$1" = "z" ]; then + echo "Missing build directory" + exit + fi + + echo "tizen build-native -C ${REL} -c gcc -a ${ARCH} -r ${RS} -j 8 -- $1" + tizen build-native -C ${REL} -c gcc -a ${ARCH} -r ${RS} -j 8 -- $1 + if [ "$?" != "0" ]; then + echo "Failed to make " $1 + exit + fi +} + +BuildAll() { + for it in ${PrjList[@]} + do + Build $it + done +} + +if [ "${1}" == "clean" ]; then + echo "#### Clean perftool : ${REL} ####" + CleanAll + rm -rf ./artifacts/${REL}/*.tpk + exit +fi + +if [ "${ARCH}" != "arm" ]; then + if [ "${ARCH}" != "aarch64" ]; then + if [ "${ARCH}" != "x86" ]; then + if [ "${ARCH}" != "x86_64" ]; then + echo "Warning: Failed to get correct architecture" + Usage + fi + fi + fi +fi + +if [ "${REL}" != "Debug" ]; then + if [ "${REL}" != "Release" ]; then + echo "Warning: Failed to get correct release mode" + Usage + fi +fi + +tizen list rootstrap | grep ${RS} +if [ "$?" != "0" ]; then + echo "Warning: Failed to get correct rootstrap. Must install the rootstrap : ${RS}" + Usage +fi + +# Clean All Project +CleanAll + +# Build All Project +BuildAll + +# Create package +tizen package -t tpk -- ${BIN_ROOT}/${REL} + +# Create artifacts directory +mkdir -p ./artifacts/${REL}/ + +# Put output to artifacts directory +cp -a ${BIN_ROOT}/${REL}/*.tpk ./artifacts/${REL}/ + diff --git a/test/test_runner_app/buildspec.json b/test/test_runner_app/buildspec.json new file mode 100644 index 0000000..5363222 --- /dev/null +++ b/test/test_runner_app/buildspec.json @@ -0,0 +1,13 @@ +{ + "description" : "Test Runner Build Specification", + + "build" : { + "6.0" : { + "archlist" : [ "arm" ], + "script" : [ + "#!/bin/bash -e", + "./build_test_runner.sh {arch} {rel} {rs_ver} {rs}" + ] + } + } +} diff --git a/test/test_runner_app/test_runner/.exportMap b/test/test_runner_app/test_runner/.exportMap new file mode 100644 index 0000000..9c5e9a2 --- /dev/null +++ b/test/test_runner_app/test_runner/.exportMap @@ -0,0 +1,3 @@ +{ + global: main; +}; diff --git a/test/test_runner_app/test_runner/inc/test_runner.h b/test/test_runner_app/test_runner/inc/test_runner.h new file mode 100644 index 0000000..bf55c48 --- /dev/null +++ b/test/test_runner_app/test_runner/inc/test_runner.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * PROPRIETARY/CONFIDENTIAL + * + * This software is the confidential and proprietary information of + * Samsung Electronics Co., Ltd. ("Confidential Information"). + * You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement + * you entered into with Samsung Electronics Co., Ltd. ("SAMSUNG"). + * + * SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY + * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE + * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, + * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + */ + +#ifndef __TEST_RUNNER_H__ +#define __TEST_RUNNER_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TEST_RUNNER" + +#define LOGI(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGD(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGE(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGW(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) + +#if !defined(PACKAGE) +#define PACKAGE "test_runner" +#endif + +bool spawn(char *const av[], char *const ev[], pid_t *childpid, int *childfd, int *exit_code); + +#endif /* __TEST_RUNNER_H__ */ + diff --git a/test/test_runner_app/test_runner/project_def.prop b/test/test_runner_app/test_runner/project_def.prop new file mode 100644 index 0000000..49d103b --- /dev/null +++ b/test/test_runner_app/test_runner/project_def.prop @@ -0,0 +1,60 @@ + +# Project Name +APPNAME = test_runner + +# Project Type +type = app + +# Project Profile +profile = wearable-4.0 + +# C/CPP Sources +USER_SRCS = src/*.c + +# EDC Sources +USER_EDCS = + +# PO Sources +USER_POS = + +# User Defines +USER_DEFS = +USER_CPP_DEFS = + +# User Undefines +USER_UNDEFS = +USER_CPP_UNDEFS = + +# User Libraries +USER_LIBS = + +# User Objects +USER_OBJS = + +# User Includes +## C Compiler +USER_C_INC_DIRS = inc +USER_INC_FILES = +## C++ Compiler +USER_CPP_INC_DIRS = +USER_CPP_INC_FILES = + +USER_INC_DIRS = $(USER_C_INC_DIRS) $(USER_CPP_INC_DIRS) + +# User Library Path +USER_LIB_DIRS = lib + +# EDC Resource Path +USER_EDCS_IMAGE_DIRS = ${OUTPUT_DIR} +USER_EDCS_SOUND_DIRS = ${OUTPUT_DIR} +USER_EDCS_FONT_DIRS = ${OUTPUT_DIR} + +# EDC Flags +USER_EXT_EDC_KEYS = + +# Resource Filter +USER_RES_INCLUDE = +USER_RES_EXCLUDE = + +USER_C_OPTS = -fdiagnostics-color +USER_CPP_OPTS = -fdiagnostics-color diff --git a/test/test_runner_app/test_runner/shared/res/test_runner.png b/test/test_runner_app/test_runner/shared/res/test_runner.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/test/test_runner_app/test_runner/shared/res/test_runner.png differ diff --git a/test/test_runner_app/test_runner/src/test_runner.c b/test/test_runner_app/test_runner/src/test_runner.c new file mode 100644 index 0000000..cdfae3e --- /dev/null +++ b/test/test_runner_app/test_runner/src/test_runner.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * PROPRIETARY/CONFIDENTIAL + * + * This software is the confidential and proprietary information of + * Samsung Electronics Co., Ltd. ("Confidential Information"). + * You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement + * you entered into with Samsung Electronics Co., Ltd. ("SAMSUNG"). + * + * SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY + * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE + * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, + * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "test_runner.h" + +static bool service_app_create(void *data) +{ + LOGI("test_runner is created"); + + return true; +} + +static void service_app_terminate(void *data) +{ + LOGI("test_runner is terminated"); + + return; +} + +static void service_app_control(app_control_h app_control, void *data) +{ + int ret; + char *value; + + pid_t childpid; + char *av[] = {"/usr/bin/nsjail", "--config", "/usr/share/runner-sandbox.cfg", "--", NULL, NULL}; + + ret = app_control_get_extra_data(app_control, "execute", &value); + switch (ret) { + case APP_CONTROL_ERROR_NONE: + av[4]=value; + LOGI("Runner Command is %s",value); + spawn(av, NULL, &childpid, NULL, NULL); + LOGI("Child pid is %d",childpid); + break; + case APP_CONTROL_ERROR_KEY_NOT_FOUND: + LOGE("Invalid command"); + break; + default: + LOGE("Failed to get argument (%d)", ret); + service_app_exit(); + break; + } +} + +int main(int argc, char **argv) +{ + char ad[50] = {0, }; + service_app_lifecycle_callback_s event_callback; + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + + return service_app_main(argc, argv, &event_callback, ad); +} diff --git a/test/test_runner_app/test_runner/src/test_runner_util.c b/test/test_runner_app/test_runner/src/test_runner_util.c new file mode 100644 index 0000000..9053b12 --- /dev/null +++ b/test/test_runner_app/test_runner/src/test_runner_util.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_runner.h" + +/* This function is supposed to accept same data as passed to execve + * (argv and envp), which can be arrays of strings as well as NULL + * pointer. + */ +char *concatenate(char *const vec[]) +{ + size_t length = 0; + for (char *const *p = vec; p && *p; p++) + length += strlen(*p) + 1; + + if (length == 0) + return strdup(""); + + char *str = (char *)malloc(length); + if (!str) + return NULL; + + char *destp = str; + char *const *vecp = vec; + while (*vecp) { + destp = stpcpy(destp, *(vecp++)); + if (*vecp) + destp = stpcpy(destp, " "); + } + + return str; +} + +static int spawn_child(char *const av[], char *const ev[]) +{ + static const int spawn_error = 127; + + execve(av[0], av, ev); + return spawn_error; +} + +bool wait_for_pid(pid_t pid, int *exit_code) +{ + int status = 0; + int r = 0; + bool is_ok; + + if (pid < 0) + return false; + + do { + r = waitpid(pid, &status, 0); + is_ok = r >= 0; + } while (!is_ok && errno == EINTR); + + if (!is_ok) { + LOGE("Error while waiting for child %d status: %m", (int)pid); + return false; + } + + /* child has terminated */ + if (WIFEXITED(status)) + r = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + r = WTERMSIG(status); + else if (WIFSTOPPED(status)) + r = WSTOPSIG(status); + + LOGD("Child with pid %d terminated with exit code %d", (int)pid, r); + if (exit_code) + *exit_code = r; + + return true; +} + +bool spawn(char *const av[], char *const ev[], pid_t *childpid, int *childfd, int *exit_code) +{ + int pipefd[2]; + if (pipe(pipefd) < 0) { + LOGE("pipe: %m"); + return false; + } + + pid_t pid = fork(); + if (pid < 0) { + LOGE("fork: %m"); + close(pipefd[0]); + close(pipefd[1]); + return false; + } else if (pid == 0) { + close(pipefd[0]); + _exit(spawn_child(av, ev)); + } + close(pipefd[1]); + + char *cmd = concatenate(av); + char *env = concatenate(ev); + LOGD("Spawned child with pid %d to execute command <%s> with environment <%s>", (int)pid, cmd, env); + free(cmd); + free(env); + + // parent + if (childpid) + *childpid = pid; + + if (childfd) { + LOGD("Leaving childfd status descriptor %d open for child status notification", pipefd[0]); + *childfd = pipefd[0]; + } else + close(pipefd[0]); + + if(childpid && exit_code) + wait_for_pid(*childpid, exit_code); + + return true; +} + + + + diff --git a/test/test_runner_app/test_runner/tizen-manifest.xml b/test/test_runner_app/test_runner/tizen-manifest.xml new file mode 100644 index 0000000..8abe89e --- /dev/null +++ b/test/test_runner_app/test_runner/tizen-manifest.xml @@ -0,0 +1,9 @@ + + + + + test_runner.png + + + +