Skip to content

Commit

Permalink
Merge ST, support utest and coverage by gtest.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Mar 4, 2021
1 parent 3bb1b67 commit 7d12c36
Show file tree
Hide file tree
Showing 11 changed files with 444 additions and 3 deletions.
24 changes: 24 additions & 0 deletions trunk/3rdparty/st-srs/.circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
jobs:
build:
docker:
- image: ossrs/srs:dev
steps:
- checkout
- run: |
make linux-debug
test:
docker:
- image: ossrs/srs:dev
steps:
- checkout
- run: |
ln -sf /usr/local/gtest utest/gtest &&
make linux-debug-gcov &&
./obj/st_utest && bash auto/codecov.sh
workflows:
version: 2
build_and_test:
jobs:
- build
- test
8 changes: 8 additions & 0 deletions trunk/3rdparty/st-srs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@ DARWIN_*_DBG
LINUX_*_DBG
obj
st.pc
.idea

gtest*
googletest-*
*.gcda
*.gcno
coverage
codecov
32 changes: 32 additions & 0 deletions trunk/3rdparty/st-srs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ TARGETS = aix-debug aix-optimized \
solaris-debug solaris-optimized \
solaris-64-debug solaris-64-optimized

UTEST_TARGETS = darwin-debug-utest linux-debug-utest \
darwin-debug-gcov linux-debug-gcov

#
# Platform specifics
#
Expand Down Expand Up @@ -282,12 +285,21 @@ endif
#
# make EXTRA_CFLAGS=-UMD_HAVE_EPOLL <target>
#
# or to enable sendmmsg(2) support:
#
# make EXTRA_CFLAGS="-DMD_HAVE_SENDMMSG -D_GNU_SOURCE"
#
# or to enable stats for ST:
#
# make EXTRA_CFLAGS=-DDEBUG_STATS
#
# or enable the coverage for utest:
# make UTEST_FLAGS="-fprofile-arcs -ftest-coverage"
#
##########################

CFLAGS += $(DEFINES) $(OTHER_FLAGS) $(EXTRA_CFLAGS)
CFLAGS += $(UTEST_FLAGS)

OBJS = $(TARGETDIR)/sched.o \
$(TARGETDIR)/stk.o \
Expand Down Expand Up @@ -347,6 +359,8 @@ unknown:
@echo
@for target in $(TARGETS); do echo $$target; done
@echo
@for target in $(UTEST_TARGETS); do echo $$target; done
@echo

st.pc: st.pc.in
sed "s/@VERSION@/${VERSION}/g" < $< > $@
Expand Down Expand Up @@ -479,5 +493,23 @@ solaris-64-debug:
solaris-64-optimized:
$(MAKE) OS="SOLARIS_64" BUILD="OPT"

darwin-debug-utest:
@echo "Build utest for state-threads"
$(MAKE) OS="DARWIN" BUILD="DBG"
cd utest && $(MAKE)
linux-debug-utest:
@echo "Build utest for state-threads"
$(MAKE) OS="LINUX" BUILD="DBG"
cd utest && $(MAKE)

darwin-debug-gcov:
@echo "Build utest with gcov for state-threads"
$(MAKE) OS="DARWIN" BUILD="DBG" UTEST_FLAGS="-fprofile-arcs -ftest-coverage" STATIC_ONLY=yes
cd utest && $(MAKE) UTEST_FLAGS="-fprofile-arcs -ftest-coverage"
linux-debug-gcov:
@echo "Build utest with gcov for state-threads"
$(MAKE) OS="LINUX" BUILD="DBG" UTEST_FLAGS="-fprofile-arcs -ftest-coverage" STATIC_ONLY=yes
cd utest && $(MAKE) UTEST_FLAGS="-fprofile-arcs -ftest-coverage"

##########################

52 changes: 49 additions & 3 deletions trunk/3rdparty/st-srs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# state-threads

![](http://ossrs.net:8000/gif/v1/sls.gif?site=github.com&path=/srs/srsst)
[![](https://circleci.com/gh/ossrs/state-threads/tree/srs.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/state-threads/tree/srs)
[![](https://codecov.io/gh/ossrs/state-threads/branch/srs/graph/badge.svg)](https://codecov.io/gh/ossrs/state-threads/branch/srs)
[![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)

Fork from http://sourceforge.net/projects/state-threads, patched for [SRS](https://github.com/ossrs/srs/tree/2.0release).
Expand All @@ -14,8 +16,8 @@ For original ST without any changes, checkout the [ST master branch](https://git
Get code:

```
git clone https://github.com/ossrs/state-threads.git st-1.9 &&
git checkout -b srs origin/srs
git clone https://github.com/ossrs/state-threads.git &&
cd state-threads && git checkout srs
```

For Linux:
Expand Down Expand Up @@ -66,9 +68,10 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patche
- [x] Support macro `MD_ST_NO_ASM` to disable ASM, [#8](https://github.com/ossrs/state-threads/issues/8).
- [x] Merge patch [srs#1282](https://github.com/ossrs/srs/issues/1282#issuecomment-445539513) to support aarch64, [#9](https://github.com/ossrs/state-threads/issues/9).
- [x] Support OSX for Apple Darwin, macOS, [#11](https://github.com/ossrs/state-threads/issues/11).
- [ ] Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12).
- [x] Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12).
- [x] Refine performance for sleep or epoll_wait(0), [#17](https://github.com/ossrs/state-threads/issues/17).
- [ ] Improve the performance of timer. [9fe8cfe5b](https://github.com/ossrs/state-threads/commit/9fe8cfe5b1c9741a2e671a46215184f267fba400), [7879c2b](https://github.com/ossrs/state-threads/commit/7879c2b), [387cddb](https://github.com/ossrs/state-threads/commit/387cddb)
- [x] Support utest by gtest and coverage by gcov/gocvr.

## GDB Tools

Expand All @@ -88,6 +91,49 @@ Important cli options:
1. `--track-origins=<yes|no> [default: no]`, Controls whether Memcheck tracks the origin of uninitialised values. By default, it does not, which means that although it can tell you that an uninitialised value is being used in a dangerous way, it cannot tell you where the uninitialised value came from. This often makes it difficult to track down the root problem.
1. `--show-reachable=<yes|no> , --show-possibly-lost=<yes|no>`, to show the using memory.

## UTest and Coverage

First of all, download [google test](https://github.com/google/googletest/releases/tag/release-1.6.0) to `utest/gtest`, check by:

```bash
ls -lh utest/gtest/include/gtest/gtest.h >/dev/null && echo yes
```

To make ST with utest and run it:

```bash
make linux-debug-gcov && ./obj/st_utest
```

> For macOS: `make darwin-debug-gcov && ./obj/st_utest`
> Run utest without coverage: `make darwin-debug-utest && ./obj/st_utest`
Then, install [gcovr](https://gcovr.com/en/stable/guide.html) for coverage:

```bash
yum install -y python2-pip &&
pip install lxml && pip install gcovr
```

> For macOS: `pip3 install gcovr`
Finally, run test and get the report

```bash
mkdir -p coverage &&
gcovr -r . -e LINUX -e DARWIN -e examples --html --html-details -o coverage/st.html &&
open coverage/st.html
```

> Note: We ignore `LINUX*` and `DARWIN*` which is `obj` actually.
Or just run locally:

```bash
bash auto/coverage.sh
```

## Docs & Analysis

* Introduction: http://ossrs.github.io/state-threads/docs/st.html
Expand Down
52 changes: 52 additions & 0 deletions trunk/3rdparty/st-srs/auto/codecov.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# In .circleci/config.yml, generate *.gcno with
# ./configure --gcov --without-research --without-librtmp && make
# and generate *.gcda by
# ./objs/srs_utest

# Workdir is objs/cover.
workdir=`pwd`/codecov && rm -rf $workdir

# Tool git is required to map the right path.
git --version >/dev/null 2>&1
ret=$?; if [[ $ret -ne 0 ]]; then echo "Tool git is required, ret=$ret"; exit $ret; fi

# Create trunk under workdir.
mkdir -p $workdir && cd $workdir
ret=$?; if [[ $ret -ne 0 ]]; then echo "Enter workdir failed, ret=$ret"; exit $ret; fi

# Collect all *.gcno and *.gcda to objs/cover.
cd $workdir && for file in $(cd .. && ls *.c); do
cp ../$file $file && echo "Copy $file" &&
if [[ -f ../obj/${file%.*}.gcno ]]; then
cp ../obj/${file%.*}.* .
fi
done
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect *.gcno and *.gcda failed, ret=$ret"; exit $ret; fi

# Generate *.gcov for coverage.
cd $workdir &&
for file in $(ls *.c); do
gcov $file -o `dirname $file`
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect $file failed, ret=$ret"; exit $ret; fi
done

# Filter the gcov files, remove utest or gtest.
cd $workdir &&
rm -f *gtest*.gcov *utest*.gcov
ret=$?; if [[ $ret -ne 0 ]]; then echo "Cook gcov files failed, ret=$ret"; exit $ret; fi

# Upload report with *.gcov
# Remark: The file codecov.yml is not neccessary. It literally depends on git.
# Note: The right path is like:
# https://codecov.io/gh/ossrs/srs/src/3.0release/trunk/src/protocol/srs_rtmp_stack.cpp
# https://codecov.io/gh/ossrs/srs/src/20fbb4466fdc8ba5d810b8570df6004063212838/trunk/src/protocol/srs_rtmp_stack.cpp
# Remark: It takes a few minutes to sync with github, so it might not available when CircleCI is done.
# https://circleci.com/gh/ossrs/srs/tree/3.0release
#
# Note: Use '-X gcov' to avoid generate the gcov files again.
cd $workdir &&
export CODECOV_TOKEN="0d616496-f781-4e7c-b285-d1f70a1cdf24" &&
bash <(curl -s https://codecov.io/bash) -X gcov &&
echo "Done" && exit 0
39 changes: 39 additions & 0 deletions trunk/3rdparty/st-srs/auto/coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

if [[ ! -f utest/gtest/include/gtest/gtest.h ]]; then
(
cd utest && rm -rf gtest &&
curl https://github.com/google/googletest/archive/release-1.6.0.tar.gz -L -o googletest-release-1.6.0.tar.gz &&
tar xf googletest-release-1.6.0.tar.gz &&
ln -sf googletest-release-1.6.0 gtest &&
echo "Setup gtest ok"
)
fi
if [[ ! -f utest/gtest/include/gtest/gtest.h ]]; then
echo "No utest/gtest, please download from https://github.com/google/googletest/releases/tag/release-1.6.0"
exit -1
else
echo "Check utest/gtest ok"
fi

if [[ $(gcovr --version >/dev/null && echo yes) != yes ]]; then
echo "Please install gcovr: https://github.com/ossrs/state-threads/tree/srs#utest-and-coverage"
exit -1
fi

IS_LINUX=yes
uname -s|grep Darwin >/dev/null && IS_DARWIN=yes && IS_LINUX=no
echo "IS_LINUX: $IS_LINUX, IS_DARWIN: $IS_DARWIN"

echo "Build and run utest"
if [[ $IS_DARWIN == yes ]]; then
make clean && make darwin-debug-gcov && ./obj/st_utest
else
make clean && make linux-debug-gcov && ./obj/st_utest
fi

echo "Generating coverage"
mkdir -p coverage &&
gcovr -r . -e LINUX -e DARWIN -e examples --html --html-details -o coverage/st.html &&
echo "Coverage report at coverage/st.html" &&
open coverage/st.html
65 changes: 65 additions & 0 deletions trunk/3rdparty/st-srs/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ unsigned long long _st_stat_recvmsg = 0;
unsigned long long _st_stat_recvmsg_eagain = 0;
unsigned long long _st_stat_sendmsg = 0;
unsigned long long _st_stat_sendmsg_eagain = 0;
unsigned long long _st_stat_sendmmsg = 0;
unsigned long long _st_stat_sendmmsg_eagain = 0;
#endif

#if EAGAIN != EWOULDBLOCK
Expand Down Expand Up @@ -831,6 +833,69 @@ int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags, st_utime_t
return n;
}

int st_sendmmsg(st_netfd_t fd, struct st_mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout)
{
#if defined(MD_HAVE_SENDMMSG) && defined(_GNU_SOURCE)
int n;
int left;
struct mmsghdr *p;

#if defined(DEBUG) && defined(DEBUG_STATS)
++_st_stat_sendmmsg;
#endif

left = (int)vlen;
while (left > 0) {
p = (struct mmsghdr*)msgvec + (vlen - left);

if ((n = sendmmsg(fd->osfd, p, left, flags)) < 0) {
if (errno == EINTR)
continue;
if (!_IO_NOT_READY_ERROR)
break;

#if defined(DEBUG) && defined(DEBUG_STATS)
++_st_stat_sendmmsg_eagain;
#endif

/* Wait until the socket becomes writable */
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
break;
}

left -= n;
}

// An error is returned only if no datagrams could be sent.
if (left == (int)vlen) {
return n;
}
return (int)vlen - left;
#else
struct st_mmsghdr *p;
int i, n;

// @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html
for (i = 0; i < (int)vlen; ++i) {
p = msgvec + i;
n = st_sendmsg(fd, &p->msg_hdr, flags, timeout);
if (n < 0) {
// An error is returned only if no datagrams could be sent.
if (i == 0) {
return n;
}
return i + 1;
}

p->msg_len = n;
}

// Returns the number of messages sent from msgvec; if this is less than vlen, the caller can retry with a
// further sendmmsg() call to send the remaining messages.
return vlen;
#endif
}


/*
* To open FIFOs or other special files.
Expand Down
8 changes: 8 additions & 0 deletions trunk/3rdparty/st-srs/public.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ extern int st_sendto(st_netfd_t fd, const void *msg, int len, const struct socka
extern int st_recvmsg(st_netfd_t fd, struct msghdr *msg, int flags, st_utime_t timeout);
extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_utime_t timeout);

// @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html
#include <sys/socket.h>
struct st_mmsghdr {
struct msghdr msg_hdr; /* Message header */
unsigned int msg_len; /* Number of bytes transmitted */
};
extern int st_sendmmsg(st_netfd_t fd, struct st_mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout);

extern st_netfd_t st_open(const char *path, int oflags, mode_t mode);

#ifdef DEBUG
Expand Down
Loading

0 comments on commit 7d12c36

Please sign in to comment.