Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tests/identity_fork.test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ifeq ($(TESTSROOTDIR),)
include ../testcase.mk
else
include $(TESTSROOTDIR)/testcase.mk
endif
ifeq ($(TEST_TIMEOUT),)
export TEST_TIMEOUT=5m
endif
32 changes: 32 additions & 0 deletions tests/identity_fork.test/runit
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
bash -n "$0" || exit 1

set -e
source ${TESTSROOTDIR}/tools/runit_common.sh

dbnm=$1

if [ "x$dbnm" == "x" ] ; then
failexit "need a DB name"
fi

if [[ -z "$CLUSTER" ]]; then
echo 'comdb2_config:default_type=local' > $CDB2_CONFIG
fi

echo '
comdb2_config:allow_pmux_route=false
' >> $CDB2_CONFIG

echo $CDB2_CONFIG > ${TESTDIR}/identity_fork_config

${TESTSBUILDDIR}/identity_fork $dbnm default > ${TESTDIR}/identity_fork_output 2>&1

# Test passes if we don't see the "Identity deleted while being accessed" error
var="$(grep "Identity deleted while being accessed" ${TESTDIR}/identity_fork_output | wc -l)"

if [ "$var" -ne "0" ] ; then
failexit "Found 'Identity deleted while being accessed' error"
fi

echo "Passed"
1 change: 1 addition & 0 deletions tests/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ add_exe(default_consumer default_consumer.c)
add_exe(emit_timeout emit_timeout.c)
add_exe(foreigndbconfig foreigndbconfig.c)
add_exe(hatest hatest.c)
add_exe(identity_fork identity_fork.cpp)
add_exe(ins_upd_del ins_upd_del.cpp)
add_exe(insblob insblob.c)
add_exe(updblob updblob.c)
Expand Down
111 changes: 111 additions & 0 deletions tests/tools/identity_fork.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cdb2api.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

pthread_t fork_tid, request_tid;
static char *dbname = NULL;
static char *tier = NULL;

void* request_thd(void *ununsed) {
cdb2_hndl_tp *db;
for (int i=0;i<10000;i++) {
int rc = cdb2_open(&db, dbname, tier, 0);
if (rc) {
fprintf(stderr, "cdb2_open failed %s\n", cdb2_errstr(db));
abort();
}
rc = cdb2_run_statement(db, "select 1");
if (rc) {
fprintf(stderr, "cdb2_run_statement failed %s\n", cdb2_errstr(db));
abort();
}
while ((rc = cdb2_next_record(db)) == CDB2_OK);
if (rc != CDB2_OK_DONE) {
abort();
}
cdb2_close(db);
}
return NULL;
}

void* fork_thd(void *p) {
for (int i=0;i<10000;i++) {
pid_t pid = fork();
if (pid == -1)
abort();
else if (pid == 0) {
int rc = execl("/bin/echo", "echo", "echo", (char*)NULL);
if (rc != 0) {
perror("execl failed");
abort();
}
// unreachable?
exit(1);
}
else {
pid_t wp;
int status;
wp = waitpid(pid, &status, 0);
if (wp != pid)
abort();
if (status != 0)
abort();
}
}
return NULL;
}


void forker(void) {
int rc = pthread_create(&fork_tid, NULL, fork_thd, NULL);
if (rc)
abort();
}

void requester(void) {
int rc = pthread_create(&request_tid, NULL, request_thd, NULL);
if (rc)
abort();
}

void waitforthd(void) {
void *ret;
int rc = pthread_join(fork_tid, &ret);
if (rc)
abort();
rc = pthread_join(request_tid, &ret);
if (rc)
abort();
}

int main(int argc, char **argv)
{
if (argc < 1) {
fprintf(stderr, "Usage: %s <dbname> \n", argv[0]);
return 1;
}

char *conf = getenv("CDB2_CONFIG");

if (conf != NULL) {
cdb2_set_comdb2db_config(conf);
tier = (char*)"default";
} else {
tier = (char*)"local";
}

dbname = argv[1];

signal(SIGPIPE, SIG_IGN);
forker();
requester();
waitforthd();
return 0;
}