aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
Diffstat (limited to 'extras')
-rw-r--r--extras/hs-test/Makefile29
-rw-r--r--extras/hs-test/README.rst10
-rw-r--r--extras/hs-test/docker/Dockerfile.curl3
-rw-r--r--extras/hs-test/docker/Dockerfile.envoy6
-rw-r--r--extras/hs-test/docker/Dockerfile.nginx3
-rw-r--r--extras/hs-test/docker/Dockerfile.nginx-http320
-rw-r--r--extras/hs-test/docker/Dockerfile.vpp1
-rw-r--r--extras/hs-test/framework_test.go8
-rw-r--r--extras/hs-test/hs_test.sh63
-rw-r--r--extras/hs-test/http_test.go280
-rw-r--r--extras/hs-test/infra/container.go52
-rw-r--r--extras/hs-test/infra/cpu.go3
-rw-r--r--extras/hs-test/infra/hst_suite.go117
-rw-r--r--extras/hs-test/infra/suite_cpu_pinning.go12
-rw-r--r--extras/hs-test/infra/suite_envoy_proxy.go36
-rw-r--r--extras/hs-test/infra/suite_iperf_linux.go4
-rw-r--r--extras/hs-test/infra/suite_ldp.go78
-rw-r--r--extras/hs-test/infra/suite_nginx_proxy.go96
-rw-r--r--extras/hs-test/infra/suite_no_topo.go78
-rw-r--r--extras/hs-test/infra/suite_ns.go127
-rw-r--r--extras/hs-test/infra/suite_veth.go11
-rw-r--r--extras/hs-test/infra/suite_vpp_proxy.go22
-rw-r--r--extras/hs-test/infra/utils.go9
-rw-r--r--extras/hs-test/infra/vppinstance.go91
-rw-r--r--extras/hs-test/iperf_linux_test.go5
-rw-r--r--extras/hs-test/ldp_test.go26
-rw-r--r--extras/hs-test/mem_leak_test.go3
-rw-r--r--extras/hs-test/nginx_test.go55
-rw-r--r--extras/hs-test/proxy_test.go57
-rw-r--r--extras/hs-test/raw_session_test.go4
-rw-r--r--extras/hs-test/resources/nginx/nginx.conf2
-rw-r--r--extras/hs-test/resources/nginx/nginx_http3.conf5
-rw-r--r--extras/hs-test/resources/nginx/nginx_proxy_mirroring.conf2
-rw-r--r--extras/hs-test/resources/nginx/vcl.conf1
-rwxr-xr-xextras/hs-test/script/build_boringssl.sh4
-rwxr-xr-xextras/hs-test/script/build_hst.sh5
-rwxr-xr-xextras/hs-test/script/build_nginx.sh5
-rwxr-xr-xextras/hs-test/script/compress.sh7
-rw-r--r--extras/hs-test/topo-containers/envoyProxy.yaml5
-rw-r--r--extras/hs-test/topo-containers/ns.yaml27
-rw-r--r--extras/hs-test/vcl_test.go16
-rwxr-xr-xextras/scripts/crcchecker.py7
-rwxr-xr-xextras/vpp_if_stats/apimock.go5
-rwxr-xr-xextras/vpp_if_stats/json_structs.go1
-rwxr-xr-xextras/vpp_if_stats/statsmock.go3
-rw-r--r--extras/vpp_if_stats/vpp_if_stats.go3
-rw-r--r--extras/vpp_if_stats/vpp_if_stats_test.go7
47 files changed, 885 insertions, 529 deletions
diff --git a/extras/hs-test/Makefile b/extras/hs-test/Makefile
index 2a501580e53..7d1242e08d8 100644
--- a/extras/hs-test/Makefile
+++ b/extras/hs-test/Makefile
@@ -74,7 +74,6 @@ help:
@echo
@echo "'make build' arguments:"
@echo " UBUNTU_VERSION - ubuntu version for docker image"
- @echo " HST_EXTENDED_TESTS - build extended tests"
@echo
@echo "'make test' arguments:"
@echo " PERSIST=[true|false] - whether clean up topology and dockers after test"
@@ -87,6 +86,7 @@ help:
@echo " PARALLEL=[n-cpus] - number of test processes to spawn to run in parallel"
@echo " REPEAT=[n] - repeat tests up to N times or until a failure occurs"
@echo " CPU0=[true|false] - use cpu0"
+ @echo " DRYRUN=[true|false] - set up containers but don't run tests"
@echo
@echo "List of all tests:"
@$(MAKE) list-tests
@@ -121,7 +121,8 @@ build-vpp-gcov:
test: .deps.ok .build.ok
@bash ./hs_test.sh --persist=$(PERSIST) --verbose=$(VERBOSE) \
--unconfigure=$(UNCONFIGURE) --debug=$(DEBUG) --test=$(TEST) --cpus=$(CPUS) \
- --vppsrc=$(VPPSRC) --parallel=$(PARALLEL) --repeat=$(REPEAT) --cpu0=$(CPU0); \
+ --vppsrc=$(VPPSRC) --parallel=$(PARALLEL) --repeat=$(REPEAT) --cpu0=$(CPU0) \
+ --dryrun=$(DRYRUN); \
./script/compress.sh $$?
@@ -130,14 +131,14 @@ test-debug: .deps.ok .build_debug.ok
@bash ./hs_test.sh --persist=$(PERSIST) --verbose=$(VERBOSE) \
--unconfigure=$(UNCONFIGURE) --debug=$(DEBUG) --test=$(TEST) --cpus=$(CPUS) \
--vppsrc=$(VPPSRC) --parallel=$(PARALLEL) --repeat=$(REPEAT) --debug_build=true \
- --cpu0=$(CPU0); \
+ --cpu0=$(CPU0) --dryrun=$(DRYRUN); \
./script/compress.sh $$?
.PHONY: test-cov
test-cov: .deps.ok .build.cov.ok
@bash ./hs_test.sh --persist=$(PERSIST) --verbose=$(VERBOSE) \
--unconfigure=$(UNCONFIGURE) --debug=$(DEBUG) --test=$(TEST-HS) --cpus=$(CPUS) \
- --vppsrc=$(VPPSRC) --cpu0=$(CPU0); \
+ --vppsrc=$(VPPSRC) --cpu0=$(CPU0) --dryrun=$(DRYRUN); \
./script/compress.sh $$?
.PHONY: test-leak
@@ -184,10 +185,19 @@ install-deps:
@apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
@touch .deps.ok
+.goimports.ok:
+ @rm -f .goimports.ok
+ go install golang.org/x/tools/cmd/goimports@v0.25.0
+ @touch .goimports.ok
+
.PHONY: checkstyle-go
-checkstyle-go:
- @output=$$(gofmt -d $${WS_ROOT}); \
- if [ -z "$$output" ]; then \
+checkstyle-go: .goimports.ok
+ $(eval GOPATH := $(shell go env GOPATH))
+ @output=$$($(GOPATH)/bin/goimports -d $${WS_ROOT}); \
+ status=$$?; \
+ if [ $$status -ne 0 ]; then \
+ exit $$status; \
+ elif [ -z "$$output" ]; then \
echo "*******************************************************************"; \
echo "Checkstyle OK."; \
echo "*******************************************************************"; \
@@ -200,9 +210,10 @@ checkstyle-go:
fi
.PHONY: fixstyle-go
-fixstyle-go:
+fixstyle-go: .goimports.ok
+ $(eval GOPATH := $(shell go env GOPATH))
@echo "Modified files:"
- @gofmt -w -l $(WS_ROOT)
+ @$(GOPATH)/bin/goimports -w -l $(WS_ROOT)
@go mod tidy
@echo "*******************************************************************"
@echo "Fixstyle done."
diff --git a/extras/hs-test/README.rst b/extras/hs-test/README.rst
index 6a4cea187c4..c62be5a84aa 100644
--- a/extras/hs-test/README.rst
+++ b/extras/hs-test/README.rst
@@ -27,7 +27,7 @@ Anatomy of a test case
**Action flow when running a test case**:
#. It starts with running ``make test``. Optional arguments are VERBOSE, PERSIST (topology configuration isn't cleaned up after test run, use ``make cleanup-hst`` to clean up),
- TEST=<test-name> to run a specific test and PARALLEL=[n-cpus].
+ TEST=<test-name> to run a specific test and PARALLEL=[n-cpus]. If you want to run multiple specific tests, separate their names with a comma.
#. ``make list-tests`` (or ``make help``) shows all tests.
#. ``Ginkgo`` looks for a spec suite in the current directory and then compiles it to a .test binary.
#. The Ginkgo test framework runs each function that was registered manually using ``Register[SuiteName]Test()``. Each of these functions correspond to a suite.
@@ -167,8 +167,8 @@ Modifying the framework
// Add custom setup code here
- s.ConfigureNetworkTopology("myTopology")
- s.LoadContainerTopology("2peerVeth")
+ s.ConfigureNetworkTopology("myNetworkTopology")
+ s.LoadContainerTopology("myContainerTopology")
}
#. In suite file, implement ``SetupTest`` method which gets executed before each test. Starting containers and
@@ -216,7 +216,7 @@ Modifying the framework
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -237,7 +237,7 @@ Modifying the framework
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(time.Minute*5))
+ }, SpecTimeout(TestTimeout))
})
#. Next step is to add test cases to the suite. For that, see section `Adding a test case`_ above
diff --git a/extras/hs-test/docker/Dockerfile.curl b/extras/hs-test/docker/Dockerfile.curl
index cbb0bbe734f..0722068b2f7 100644
--- a/extras/hs-test/docker/Dockerfile.curl
+++ b/extras/hs-test/docker/Dockerfile.curl
@@ -3,13 +3,12 @@ ARG UBUNTU_VERSION
FROM ubuntu:${UBUNTU_VERSION}
RUN apt-get update \
- && apt-get install -y gcc git make autoconf libtool pkg-config cmake ninja-build golang \
+ && apt-get install -y xz-utils wget \
&& rm -rf /var/lib/apt/lists/*
COPY script/build_curl.sh /build_curl.sh
COPY resources/curl/* /tmp/
RUN fallocate -l 10MB /tmp/testFile
-RUN apt-get update && apt-get install wget
RUN /build_curl.sh
CMD ["/bin/sh"]
diff --git a/extras/hs-test/docker/Dockerfile.envoy b/extras/hs-test/docker/Dockerfile.envoy
new file mode 100644
index 00000000000..cadb9b14a76
--- /dev/null
+++ b/extras/hs-test/docker/Dockerfile.envoy
@@ -0,0 +1,6 @@
+FROM envoyproxy/envoy-contrib:v1.31-latest
+
+RUN chmod go+r /etc/envoy/envoy.yaml
+RUN chown envoy:envoy /dev/stdout /dev/stderr
+
+ENTRYPOINT ["/bin/sh", "-c", "envoy --log-format [%t][%l][%g:%#]%_ --concurrency 2 -c /etc/envoy/envoy.yaml"] \ No newline at end of file
diff --git a/extras/hs-test/docker/Dockerfile.nginx b/extras/hs-test/docker/Dockerfile.nginx
index 386f8e90016..78a75d44a31 100644
--- a/extras/hs-test/docker/Dockerfile.nginx
+++ b/extras/hs-test/docker/Dockerfile.nginx
@@ -7,11 +7,10 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*
COPY vpp-data/lib/* /usr/lib/
-COPY resources/nginx/vcl.conf /vcl.conf
COPY resources/nginx/nginx.conf /nginx.conf
COPY script/nginx_ldp.sh /usr/bin/nginx_ldp.sh
-ENV VCL_CONFIG=/vcl.conf
+ENV VCL_CONFIG=/tmp/nginx/vcl.conf
ENV LDP=/usr/lib/libvcl_ldpreload.so
ENV LDP_DEBUG=0
ENV VCL_DEBUG=0
diff --git a/extras/hs-test/docker/Dockerfile.nginx-http3 b/extras/hs-test/docker/Dockerfile.nginx-http3
index 8b2f8406d38..fc905376986 100644
--- a/extras/hs-test/docker/Dockerfile.nginx-http3
+++ b/extras/hs-test/docker/Dockerfile.nginx-http3
@@ -3,16 +3,16 @@ ARG UBUNTU_VERSION
FROM ubuntu:${UBUNTU_VERSION}
RUN apt-get update \
- && apt-get install -y gcc git make autoconf libtool pkg-config cmake ninja-build golang \
- && rm -rf /var/lib/apt/lists/*
+ && apt-get install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring libunwind-dev
+RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
+| tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
+RUN echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
+ http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
+ | tee /etc/apt/sources.list.d/nginx.list
+RUN bash -c 'echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
+| tee /etc/apt/preferences.d/99nginx'
-COPY script/build_boringssl.sh /build_boringssl.sh
-RUN git clone https://boringssl.googlesource.com/boringssl
-RUN ./build_boringssl.sh
-
-COPY script/build_nginx.sh /build_nginx.sh
-RUN git clone https://github.com/nginx/nginx
-RUN ./build_nginx.sh
+RUN apt update && apt install -y nginx=1.26.2-1~jammy
COPY vpp-data/lib/* /usr/lib/
COPY resources/nginx/vcl.conf /vcl.conf
@@ -27,4 +27,4 @@ ENV LDP_DEBUG=0
ENV VCL_DEBUG=0
ENV LDP_SID_BIT=8
-ENTRYPOINT ["nginx_ldp.sh", "/usr/local/nginx/sbin/nginx", "-c", "/nginx.conf"]
+ENTRYPOINT ["nginx_ldp.sh", "nginx", "-c", "/nginx.conf"]
diff --git a/extras/hs-test/docker/Dockerfile.vpp b/extras/hs-test/docker/Dockerfile.vpp
index 82a1a1a73d3..5f5d41ce610 100644
--- a/extras/hs-test/docker/Dockerfile.vpp
+++ b/extras/hs-test/docker/Dockerfile.vpp
@@ -13,6 +13,7 @@ COPY \
$DIR/af_packet_plugin.so \
$DIR/hs_apps_plugin.so \
$DIR/http_plugin.so \
+ $DIR/http_unittest_plugin.so \
$DIR/unittest_plugin.so \
$DIR/quic_plugin.so \
$DIR/http_static_plugin.so \
diff --git a/extras/hs-test/framework_test.go b/extras/hs-test/framework_test.go
index 91cb1032bba..a578fb15573 100644
--- a/extras/hs-test/framework_test.go
+++ b/extras/hs-test/framework_test.go
@@ -15,9 +15,9 @@ import (
func TestHst(t *testing.T) {
if *IsVppDebug {
// 30 minute timeout so that the framework won't timeout while debugging
- SuiteTimeout = time.Minute * 30
+ TestTimeout = time.Minute * 30
} else {
- SuiteTimeout = time.Minute * 5
+ TestTimeout = time.Minute * 5
}
output, err := os.ReadFile("/sys/devices/system/node/online")
@@ -33,4 +33,8 @@ func TestHst(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "HST")
+ if *DryRun || *IsPersistent {
+ fmt.Println("\033[36m" + "Use 'make cleanup-hst' to remove IP files, " +
+ "namespaces and containers. \nPPID: " + ppid + "\033[0m")
+ }
}
diff --git a/extras/hs-test/hs_test.sh b/extras/hs-test/hs_test.sh
index 85c0dd72705..59edf57afc2 100644
--- a/extras/hs-test/hs_test.sh
+++ b/extras/hs-test/hs_test.sh
@@ -3,14 +3,16 @@
source vars
args=
-single_test=0
+focused_test=0
persist_set=0
+dryrun_set=0
unconfigure_set=0
debug_set=0
leak_check_set=0
debug_build=
ginkgo_args=
-tc_name=
+tc_names=()
+dryrun=
for i in "$@"
do
@@ -55,13 +57,12 @@ case "${i}" in
args="$args -vppsrc ${i#*=}"
;;
--test=*)
- tc_name="${i#*=}"
- if [ "$tc_name" != "all" ]; then
- single_test=1
- ginkgo_args="$ginkgo_args --focus $tc_name -vv"
+ tc_list="${i#*=}"
+ ginkgo_args="$ginkgo_args -v"
+ if [ "$tc_list" != "all" ]; then
+ focused_test=1
+ IFS=',' read -r -a tc_names <<< "$tc_list"
args="$args -verbose"
- else
- ginkgo_args="$ginkgo_args -v"
fi
;;
--parallel=*)
@@ -76,6 +77,13 @@ case "${i}" in
args="$args -cpu0"
fi
;;
+ --dryrun=*)
+ dryrun="${i#*=}"
+ if [ "$dryrun" = "true" ]; then
+ args="$args -dryrun"
+ dryrun_set=1
+ fi
+ ;;
--leak_check=*)
leak_check="${i#*=}"
if [ "$leak_check" = "true" ]; then
@@ -86,32 +94,41 @@ case "${i}" in
esac
done
-if [ $single_test -eq 0 ] && [ $persist_set -eq 1 ]; then
- echo "persist flag is not supported while running all tests!"
- exit 1
+if [ ${#tc_names[@]} -gt 1 ]
+then
+ focused_test=0
+fi
+
+for name in "${tc_names[@]}"; do
+ ginkgo_args="$ginkgo_args --focus $name"
+done
+
+if [ $focused_test -eq 0 ] && { [ $persist_set -eq 1 ] || [ $dryrun_set -eq 1 ]; }; then
+ echo -e "\e[1;31mpersist/dryrun flag is not supported while running all tests!\e[1;0m"
+ exit 2
fi
-if [ $unconfigure_set -eq 1 ] && [ $single_test -eq 0 ]; then
- echo "a single test has to be specified when unconfigure is set"
- exit 1
+if [ $unconfigure_set -eq 1 ] && [ $focused_test -eq 0 ]; then
+ echo -e "\e[1;31ma single test has to be specified when unconfigure is set\e[1;0m"
+ exit 2
fi
if [ $persist_set -eq 1 ] && [ $unconfigure_set -eq 1 ]; then
- echo "setting persist flag and unconfigure flag is not allowed"
- exit 1
+ echo -e "\e[1;31msetting persist flag and unconfigure flag is not allowed\e[1;0m"
+ exit 2
fi
-if [ $single_test -eq 0 ] && [ $debug_set -eq 1 ]; then
- echo "VPP debug flag is not supported while running all tests!"
- exit 1
+if [ $focused_test -eq 0 ] && [ $debug_set -eq 1 ]; then
+ echo -e "\e[1;31mVPP debug flag is not supported while running all tests!\e[1;0m"
+ exit 2
fi
if [ $leak_check_set -eq 1 ]; then
- if [ $single_test -eq 0 ]; then
- echo "a single test has to be specified when leak_check is set"
- exit 1
+ if [ $focused_test -eq 0 ]; then
+ echo -e "\e[1;31ma single test has to be specified when leak_check is set\e[1;0m"
+ exit 2
fi
- ginkgo_args="--focus $tc_name"
+ ginkgo_args="--focus ${tc_names[0]}"
sudo -E go run github.com/onsi/ginkgo/v2/ginkgo $ginkgo_args -- $args
exit 0
fi
diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go
index bfd2d34483c..902d6efacfc 100644
--- a/extras/hs-test/http_test.go
+++ b/extras/hs-test/http_test.go
@@ -3,8 +3,6 @@ package main
import (
"bytes"
"fmt"
- "github.com/onsi/gomega/ghttp"
- "github.com/onsi/gomega/gmeasure"
"io"
"math/rand"
"net"
@@ -12,9 +10,13 @@ import (
"net/http/httptrace"
"os"
"strconv"
+ "strings"
"sync"
"time"
+ "github.com/onsi/gomega/ghttp"
+ "github.com/onsi/gomega/gmeasure"
+
. "fd.io/hs-test/infra"
. "github.com/onsi/ginkgo/v2"
)
@@ -29,18 +31,22 @@ func init() {
HttpContentLengthTest, HttpStaticBuildInUrlGetIfListTest, HttpStaticBuildInUrlGetVersionTest,
HttpStaticMacTimeTest, HttpStaticBuildInUrlGetVersionVerboseTest, HttpVersionNotSupportedTest,
HttpInvalidContentLengthTest, HttpInvalidTargetSyntaxTest, HttpStaticPathTraversalTest, HttpUriDecodeTest,
- HttpHeadersTest, HttpStaticFileHandlerTest, HttpStaticFileHandlerDefaultMaxAgeTest, HttpClientTest, HttpClientErrRespTest, HttpClientPostFormTest,
- HttpClientPostFileTest, HttpClientPostFilePtrTest, AuthorityFormTargetTest, HttpRequestLineTest)
+ HttpHeadersTest, HttpStaticFileHandlerTest, HttpStaticFileHandlerDefaultMaxAgeTest, HttpClientTest,
+ HttpClientErrRespTest, HttpClientPostFormTest, HttpClientGet128kbResponseTest, HttpClientGetResponseBodyTest,
+ HttpClientGetNoResponseBodyTest, HttpClientPostFileTest, HttpClientPostFilePtrTest, HttpUnitTest,
+ HttpRequestLineTest, HttpClientGetTimeout, HttpStaticFileHandlerWrkTest, HttpStaticUrlHandlerWrkTest, HttpConnTimeoutTest)
RegisterNoTopoSoloTests(HttpStaticPromTest, HttpGetTpsTest, HttpGetTpsInterruptModeTest, PromConcurrentConnectionsTest,
- PromMemLeakTest, HttpClientPostMemLeakTest, HttpInvalidClientRequestMemLeakTest, HttpPostTpsTest, HttpPostTpsInterruptModeTest)
+ PromMemLeakTest, HttpClientPostMemLeakTest, HttpInvalidClientRequestMemLeakTest, HttpPostTpsTest, HttpPostTpsInterruptModeTest,
+ PromConsecutiveConnectionsTest)
}
const wwwRootPath = "/tmp/www_root"
+const defaultHttpTimeout = time.Second * 10
func httpDownloadBenchmark(s *HstSuite, experiment *gmeasure.Experiment, data interface{}) {
url, isValid := data.(string)
s.AssertEqual(true, isValid)
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", url, nil)
s.AssertNil(err, fmt.Sprint(err))
t := time.Now()
@@ -73,7 +79,7 @@ func httpUploadBenchmark(s *HstSuite, experiment *gmeasure.Experiment, data inte
s.AssertEqual(true, isValid)
body := make([]byte, 10485760)
_, err := rand.Read(body)
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
s.AssertNil(err, fmt.Sprint(err))
t := time.Now()
@@ -130,7 +136,7 @@ func HttpPersistentConnectionTest(s *NoTopoSuite) {
s.AssertHttpContentLength(resp, int64(0))
o1 := vpp.Vppctl("show session verbose proto http state ready")
s.Log(o1)
- s.AssertContains(o1, "ESTABLISHED")
+ s.AssertContains(o1, "established")
req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test1", nil)
s.AssertNil(err, fmt.Sprint(err))
@@ -148,7 +154,7 @@ func HttpPersistentConnectionTest(s *NoTopoSuite) {
s.AssertHttpBody(resp, "hello")
o2 := vpp.Vppctl("show session verbose proto http state ready")
s.Log(o2)
- s.AssertContains(o2, "ESTABLISHED")
+ s.AssertContains(o2, "established")
s.AssertEqual(o1, o2)
req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test2", nil)
@@ -162,9 +168,8 @@ func HttpPersistentConnectionTest(s *NoTopoSuite) {
s.AssertHttpBody(resp, "some data")
o2 = vpp.Vppctl("show session verbose proto http state ready")
s.Log(o2)
- s.AssertContains(o2, "ESTABLISHED")
+ s.AssertContains(o2, "established")
s.AssertEqual(o1, o2)
-
}
func HttpPipeliningTest(s *NoTopoSuite) {
@@ -192,7 +197,7 @@ func HttpPipeliningTest(s *NoTopoSuite) {
s.AssertNil(err, fmt.Sprint(err))
s.AssertEqual(n, len([]rune(req2)))
reply := make([]byte, 1024)
- n, err = conn.Read(reply)
+ _, err = conn.Read(reply)
s.AssertNil(err, fmt.Sprint(err))
s.Log(string(reply))
s.AssertContains(string(reply), "delayed data", "first request response not received")
@@ -293,6 +298,7 @@ func HttpClientPostFormTest(s *NoTopoSuite) {
s.LogHttpReq(true),
ghttp.VerifyRequest("POST", "/test"),
ghttp.VerifyContentType("application/x-www-form-urlencoded"),
+ ghttp.VerifyHeaderKV("Hello", "World"),
ghttp.VerifyBody([]byte(body)),
ghttp.RespondWith(http.StatusOK, nil),
))
@@ -301,18 +307,100 @@ func HttpClientPostFormTest(s *NoTopoSuite) {
uri := "http://" + serverAddress + "/80"
vpp := s.GetContainerByName("vpp").VppInstance
- o := vpp.Vppctl("http post uri " + uri + " target /test data " + body)
+ o := vpp.Vppctl("http client post verbose header Hello:World uri " + uri + " target /test data " + body)
s.Log(o)
- s.AssertNotContains(o, "error")
+ s.AssertContains(o, "200 OK")
+}
+
+func HttpClientGetResponseBodyTest(s *NoTopoSuite) {
+ response := "<body>hello world</body>"
+ size := len(response)
+ httpClientGet(s, response, size)
+}
+
+func HttpClientGet128kbResponseTest(s *NoTopoSuite) {
+ response := strings.Repeat("a", 128*1024)
+ size := len(response)
+ httpClientGet(s, response, size)
+}
+
+func HttpClientGetNoResponseBodyTest(s *NoTopoSuite) {
+ response := ""
+ httpClientGet(s, response, 0)
+}
+
+func httpClientGet(s *NoTopoSuite, response string, size int) {
+ serverAddress := s.HostAddr()
+ vpp := s.GetContainerByName("vpp").VppInstance
+
+ server := ghttp.NewUnstartedServer()
+ l, err := net.Listen("tcp", serverAddress+":80")
+ s.AssertNil(err, fmt.Sprint(err))
+ server.HTTPTestServer.Listener = l
+ server.AppendHandlers(
+ ghttp.CombineHandlers(
+ s.LogHttpReq(false),
+ ghttp.VerifyRequest("GET", "/test"),
+ ghttp.VerifyHeaderKV("Hello", "World"),
+ ghttp.VerifyHeaderKV("Test-H2", "Test-K2"),
+ ghttp.RespondWith(http.StatusOK, string(response), http.Header{"Content-Length": {strconv.Itoa(size)}}),
+ ))
+ server.Start()
+ defer server.Close()
+
+ uri := "http://" + serverAddress + "/80"
+ cmd := "http client use-ptr verbose header Hello:World header Test-H2:Test-K2 save-to response.txt uri " + uri + " target /test"
+
+ o := vpp.Vppctl(cmd)
+ outputLen := len(o)
+ if outputLen > 500 {
+ s.Log(o[:500])
+ s.Log("* HST Framework: output limited to 500 chars to avoid flooding the console. Output length: " + fmt.Sprint(outputLen))
+ } else {
+ s.Log(o)
+ }
+ s.AssertContains(o, "200 OK")
+ s.AssertContains(o, response)
+ s.AssertContains(o, "Content-Length: "+strconv.Itoa(size))
+
+ file_contents := vpp.Container.Exec(false, "cat /tmp/response.txt")
+ s.AssertContains(file_contents, response)
+}
+
+func HttpClientGetTimeout(s *NoTopoSuite) {
+ serverAddress := s.HostAddr()
+ vpp := s.GetContainerByName("vpp").VppInstance
+
+ server := ghttp.NewUnstartedServer()
+ l, err := net.Listen("tcp", serverAddress+":"+s.GetPortFromPpid())
+ s.AssertNil(err, fmt.Sprint(err))
+ server.HTTPTestServer.Listener = l
+ server.AppendHandlers(
+ ghttp.CombineHandlers(
+ s.LogHttpReq(false),
+ ghttp.VerifyRequest("GET", "/timeout"),
+ http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ time.Sleep(5 * time.Second)
+ }),
+ ghttp.RespondWith(http.StatusOK, nil),
+ ))
+ server.Start()
+ defer server.Close()
+ uri := "http://" + serverAddress + "/" + s.GetPortFromPpid()
+ cmd := "http client verbose timeout 1 uri " + uri + " target /timeout"
+
+ o := vpp.Vppctl(cmd)
+ s.Log(o)
+ s.AssertContains(o, "error: timeout")
}
func httpClientPostFile(s *NoTopoSuite, usePtr bool, fileSize int) {
serverAddress := s.HostAddr()
vpp := s.GetContainerByName("vpp").VppInstance
fileName := "/tmp/test_file.txt"
- s.Log(vpp.Container.Exec("fallocate -l " + strconv.Itoa(fileSize) + " " + fileName))
- s.Log(vpp.Container.Exec("ls -la " + fileName))
+ s.Log(vpp.Container.Exec(false, "fallocate -l "+strconv.Itoa(fileSize)+" "+fileName))
+ s.Log(vpp.Container.Exec(false, "ls -la "+fileName))
server := ghttp.NewUnstartedServer()
l, err := net.Listen("tcp", serverAddress+":80")
@@ -330,14 +418,14 @@ func httpClientPostFile(s *NoTopoSuite, usePtr bool, fileSize int) {
defer server.Close()
uri := "http://" + serverAddress + "/80"
- cmd := "http post uri " + uri + " target /test file " + fileName
+ cmd := "http client post verbose uri " + uri + " target /test file " + fileName
if usePtr {
cmd += " use-ptr"
}
o := vpp.Vppctl(cmd)
s.Log(o)
- s.AssertNotContains(o, "error")
+ s.AssertContains(o, "200 OK")
}
func HttpClientPostFileTest(s *NoTopoSuite) {
@@ -348,24 +436,11 @@ func HttpClientPostFilePtrTest(s *NoTopoSuite) {
httpClientPostFile(s, true, 131072)
}
-func cliTestAuthority(s *NoTopoSuite, authority string) {
- o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
- s.AssertNotContains(o, "error")
- s.AssertContains(o, authority)
-}
-
-func cliTestAuthorityError(s *NoTopoSuite, authority string) {
- o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
- s.AssertContains(o, "error")
-}
-
-func AuthorityFormTargetTest(s *NoTopoSuite) {
- cliTestAuthority(s, "10.10.2.45:20")
- cliTestAuthority(s, "[dead:beef::1234]:443")
- cliTestAuthorityError(s, "example.com:80")
- cliTestAuthorityError(s, "10.10.2.45")
- cliTestAuthorityError(s, "1000.10.2.45:20")
- cliTestAuthorityError(s, "[xyz0::1234]:443")
+func HttpUnitTest(s *NoTopoSuite) {
+ vpp := s.GetContainerByName("vpp").VppInstance
+ o := vpp.Vppctl("test http all")
+ s.Log(o)
+ s.AssertNotContains(o, "FAIL")
}
func HttpStaticPromTest(s *NoTopoSuite) {
@@ -375,7 +450,7 @@ func HttpStaticPromTest(s *NoTopoSuite) {
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
s.Log(vpp.Vppctl("prom enable"))
time.Sleep(time.Second * 5)
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/"+query, nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -389,8 +464,8 @@ func HttpStaticPromTest(s *NoTopoSuite) {
s.AssertNil(err, fmt.Sprint(err))
}
-func promReq(s *NoTopoSuite, url string) {
- client := NewHttpClient()
+func promReq(s *NoTopoSuite, url string, timeout time.Duration) {
+ client := NewHttpClient(timeout)
req, err := http.NewRequest("GET", url, nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -404,7 +479,7 @@ func promReq(s *NoTopoSuite, url string) {
func promReqWg(s *NoTopoSuite, url string, wg *sync.WaitGroup) {
defer GinkgoRecover()
defer wg.Done()
- promReq(s, url)
+ promReq(s, url, defaultHttpTimeout)
}
func PromConcurrentConnectionsTest(s *NoTopoSuite) {
@@ -425,6 +500,20 @@ func PromConcurrentConnectionsTest(s *NoTopoSuite) {
s.Log(vpp.Vppctl("show session verbose proto http"))
}
+func PromConsecutiveConnectionsTest(s *NoTopoSuite) {
+ vpp := s.GetContainerByName("vpp").VppInstance
+ serverAddress := s.VppAddr()
+ url := "http://" + serverAddress + ":80/stats.prom"
+
+ s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
+ s.Log(vpp.Vppctl("prom enable"))
+ time.Sleep(time.Second * 5)
+
+ for i := 0; i < 1000; i++ {
+ promReq(s, url, time.Millisecond*500)
+ }
+}
+
func PromMemLeakTest(s *NoTopoSuite) {
s.SkipUnlessLeakCheck()
@@ -440,7 +529,7 @@ func PromMemLeakTest(s *NoTopoSuite) {
time.Sleep(time.Second * 3)
/* warmup request (FIB) */
- promReq(s, url)
+ promReq(s, url, defaultHttpTimeout)
vpp.EnableMemoryTrace()
traces1, err := vpp.GetMemoryTrace()
@@ -449,7 +538,7 @@ func PromMemLeakTest(s *NoTopoSuite) {
/* collect stats couple of times */
for i := 0; i < 5; i++ {
time.Sleep(time.Second * 1)
- promReq(s, url)
+ promReq(s, url, defaultHttpTimeout)
}
/* let's give it some time to clean up sessions */
@@ -577,6 +666,39 @@ func HttpInvalidClientRequestMemLeakTest(s *NoTopoSuite) {
}
+func runWrkPerf(s *NoTopoSuite) {
+ nConnections := 1000
+ serverAddress := s.VppAddr()
+
+ wrkCont := s.GetContainerByName("wrk")
+ args := fmt.Sprintf("-c %d -t 2 -d 30s http://%s:80/64B", nConnections, serverAddress)
+ wrkCont.ExtraRunningArgs = args
+ wrkCont.Run()
+ s.Log("Please wait for 30s, test is running.")
+ o, err := wrkCont.GetOutput()
+ s.Log(o)
+ s.AssertEmpty(err, "err: '%s'", err)
+}
+
+func HttpStaticFileHandlerWrkTest(s *NoTopoSuite) {
+ vpp := s.GetContainerByName("vpp").VppInstance
+ serverAddress := s.VppAddr()
+ vpp.Container.Exec(false, "mkdir -p "+wwwRootPath)
+ content := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ err := vpp.Container.CreateFile(wwwRootPath+"/64B", content)
+ s.AssertNil(err, fmt.Sprint(err))
+ s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 private-segment-size 256m"))
+ runWrkPerf(s)
+}
+
+func HttpStaticUrlHandlerWrkTest(s *NoTopoSuite) {
+ vpp := s.GetContainerByName("vpp").VppInstance
+ serverAddress := s.VppAddr()
+ s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers private-segment-size 256m"))
+ s.Log(vpp.Vppctl("test-url-handler enable"))
+ runWrkPerf(s)
+}
+
func HttpStaticFileHandlerDefaultMaxAgeTest(s *NoTopoSuite) {
HttpStaticFileHandlerTestFunction(s, "default")
}
@@ -598,7 +720,7 @@ func HttpStaticFileHandlerTestFunction(s *NoTopoSuite, max_age string) {
content2 := "<html><body><p>Page</p></body></html>"
vpp := s.GetContainerByName("vpp").VppInstance
- vpp.Container.Exec("mkdir -p " + wwwRootPath)
+ vpp.Container.Exec(false, "mkdir -p "+wwwRootPath)
err := vpp.Container.CreateFile(wwwRootPath+"/index.html", content)
s.AssertNil(err, fmt.Sprint(err))
err = vpp.Container.CreateFile(wwwRootPath+"/page.html", content2)
@@ -606,7 +728,7 @@ func HttpStaticFileHandlerTestFunction(s *NoTopoSuite, max_age string) {
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug cache-size 2m " + maxAgeFormatted))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/index.html", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -654,14 +776,14 @@ func HttpStaticFileHandlerTestFunction(s *NoTopoSuite, max_age string) {
func HttpStaticPathTraversalTest(s *NoTopoSuite) {
vpp := s.GetContainerByName("vpp").VppInstance
- vpp.Container.Exec("mkdir -p " + wwwRootPath)
- vpp.Container.Exec("mkdir -p " + "/tmp/secret_folder")
+ vpp.Container.Exec(false, "mkdir -p "+wwwRootPath)
+ vpp.Container.Exec(false, "mkdir -p "+"/tmp/secret_folder")
err := vpp.Container.CreateFile("/tmp/secret_folder/secret_file.txt", "secret")
s.AssertNil(err, fmt.Sprint(err))
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/../secret_folder/secret_file.txt", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -676,13 +798,13 @@ func HttpStaticPathTraversalTest(s *NoTopoSuite) {
func HttpStaticMovedTest(s *NoTopoSuite) {
vpp := s.GetContainerByName("vpp").VppInstance
- vpp.Container.Exec("mkdir -p " + wwwRootPath + "/tmp.aaa")
+ vpp.Container.Exec(false, "mkdir -p "+wwwRootPath+"/tmp.aaa")
err := vpp.Container.CreateFile(wwwRootPath+"/tmp.aaa/index.html", "<html><body><p>Hello</p></body></html>")
s.AssertNil(err, fmt.Sprint(err))
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/tmp.aaa", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -698,11 +820,11 @@ func HttpStaticMovedTest(s *NoTopoSuite) {
func HttpStaticNotFoundTest(s *NoTopoSuite) {
vpp := s.GetContainerByName("vpp").VppInstance
- vpp.Container.Exec("mkdir -p " + wwwRootPath)
+ vpp.Container.Exec(false, "mkdir -p "+wwwRootPath)
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/notfound.html", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -720,7 +842,7 @@ func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
vpp.Vppctl("http cli server")
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -738,7 +860,7 @@ func HttpCliBadRequestTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
vpp.Vppctl("http cli server")
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -753,10 +875,10 @@ func HttpCliBadRequestTest(s *NoTopoSuite) {
func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
vpp := s.GetContainerByName("vpp").VppInstance
serverAddress := s.VppAddr()
- s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
+ s.Log(vpp.Vppctl("http static server uri tls://" + serverAddress + "/80 url-handlers debug"))
- client := NewHttpClient()
- req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json", nil)
+ client := NewHttpClient(defaultHttpTimeout)
+ req, err := http.NewRequest("GET", "https://"+serverAddress+":80/version.json", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
s.AssertNil(err, fmt.Sprint(err))
@@ -779,7 +901,7 @@ func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json?verbose=true", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -803,7 +925,7 @@ func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_list.json", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -823,7 +945,7 @@ func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_stats.json", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -852,7 +974,7 @@ func HttpStaticBuildInUrlPostIfStatsTest(s *NoTopoSuite) {
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
body := []byte(s.VppIfName())
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("POST",
"http://"+serverAddress+":80/interface_stats.json", bytes.NewBuffer(body))
s.AssertNil(err, fmt.Sprint(err))
@@ -873,7 +995,7 @@ func HttpStaticMacTimeTest(s *NoTopoSuite) {
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
s.Log(vpp.Vppctl("mactime enable-disable " + s.VppIfName()))
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/mactime.json", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -1044,7 +1166,7 @@ func HttpMethodNotImplementedTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
vpp.Vppctl("http cli server")
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("OPTIONS", "http://"+serverAddress+":80/show/version", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -1071,7 +1193,7 @@ func HttpUriDecodeTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
vpp.Vppctl("http cli server")
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/sh%6fw%20versio%6E%20verbose", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -1143,7 +1265,7 @@ func HeaderServerTest(s *NoTopoSuite) {
serverAddress := s.VppAddr()
vpp.Vppctl("http cli server")
- client := NewHttpClient()
+ client := NewHttpClient(defaultHttpTimeout)
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/show/version", nil)
s.AssertNil(err, fmt.Sprint(err))
resp, err := client.Do(req)
@@ -1154,3 +1276,33 @@ func HeaderServerTest(s *NoTopoSuite) {
s.AssertHttpHeaderWithValue(resp, "Server", "http_cli_server")
s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
}
+
+func HttpConnTimeoutTest(s *NoTopoSuite) {
+ vpp := s.GetContainerByName("vpp").VppInstance
+ serverAddress := s.VppAddr()
+ s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug keepalive-timeout 2"))
+
+ req := "GET /version.json HTTP/1.1\r\nHost:" + serverAddress + ":80\r\nUser-Agent:test\r\n\r\n"
+ conn, err := net.DialTimeout("tcp", serverAddress+":80", time.Second*30)
+ s.AssertNil(err, fmt.Sprint(err))
+ defer conn.Close()
+ err = conn.SetDeadline(time.Now().Add(time.Second * 30))
+ s.AssertNil(err, fmt.Sprint(err))
+ _, err = conn.Write([]byte(req))
+ s.AssertNil(err, fmt.Sprint(err))
+ reply := make([]byte, 1024)
+ _, err = conn.Read(reply)
+ s.AssertNil(err, fmt.Sprint(err))
+ s.AssertContains(string(reply), "HTTP/1.1 200 OK")
+ s.Log(vpp.Vppctl("show session verbose 2"))
+
+ s.Log("waiting for close on the server side")
+ time.Sleep(time.Second * 5)
+ s.Log(vpp.Vppctl("show session verbose 2"))
+
+ _, err = conn.Write([]byte(req))
+ s.AssertNil(err, fmt.Sprint(err))
+ reply = make([]byte, 1024)
+ _, err = conn.Read(reply)
+ s.AssertMatchError(err, io.EOF, "connection not closed by server")
+}
diff --git a/extras/hs-test/infra/container.go b/extras/hs-test/infra/container.go
index 974d1547c03..cc79a5cbb18 100644
--- a/extras/hs-test/infra/container.go
+++ b/extras/hs-test/infra/container.go
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
- "github.com/docker/go-units"
"os"
"os/exec"
"regexp"
@@ -14,6 +13,8 @@ import (
"text/template"
"time"
+ "github.com/docker/go-units"
+
"github.com/cilium/cilium/pkg/sysctl"
containerTypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
@@ -328,9 +329,13 @@ func (c *Container) getVolumesAsSlice() []string {
core_pattern, err := sysctl.Read("kernel.core_pattern")
if err == nil {
- index := strings.LastIndex(core_pattern, "/")
- core_pattern = core_pattern[:index]
- volumeSlice = append(volumeSlice, c.Suite.getLogDirPath()+":"+core_pattern)
+ if len(core_pattern) > 0 && core_pattern[0] != '|' {
+ index := strings.LastIndex(core_pattern, "/")
+ core_pattern = core_pattern[:index]
+ volumeSlice = append(volumeSlice, c.Suite.getLogDirPath()+":"+core_pattern)
+ } else {
+ c.Suite.Log(fmt.Sprintf("core_pattern \"%s\" starts with pipe, ignoring", core_pattern))
+ }
} else {
c.Suite.Log(err)
}
@@ -415,6 +420,19 @@ func (c *Container) CreateFile(destFileName string, content string) error {
return nil
}
+func (c *Container) CreateFileInWorkDir(fileName string, contents string) error {
+ file, err := os.Create(c.GetHostWorkDir() + "/" + fileName)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ _, err = file.Write([]byte(contents))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
func (c *Container) GetFile(sourceFileName, targetFileName string) error {
cmd := exec.Command("docker", "cp", c.Name+":"+sourceFileName, targetFileName)
return cmd.Run()
@@ -424,19 +442,29 @@ func (c *Container) GetFile(sourceFileName, targetFileName string) error {
* Executes in detached mode so that the started application can continue to run
* without blocking execution of test
*/
-func (c *Container) ExecServer(command string, arguments ...any) {
+func (c *Container) ExecServer(useEnvVars bool, command string, arguments ...any) {
+ var envVars string
serverCommand := fmt.Sprintf(command, arguments...)
- containerExecCommand := "docker exec -d" + c.getEnvVarsAsCliOption() +
- " " + c.Name + " " + serverCommand
+ if useEnvVars {
+ envVars = c.getEnvVarsAsCliOption()
+ } else {
+ envVars = ""
+ }
+ containerExecCommand := fmt.Sprintf("docker exec -d %s %s %s", envVars, c.Name, serverCommand)
GinkgoHelper()
c.Suite.Log(containerExecCommand)
c.Suite.AssertNil(exechelper.Run(containerExecCommand))
}
-func (c *Container) Exec(command string, arguments ...any) string {
- cliCommand := fmt.Sprintf(command, arguments...)
- containerExecCommand := "docker exec" + c.getEnvVarsAsCliOption() +
- " " + c.Name + " " + cliCommand
+func (c *Container) Exec(useEnvVars bool, command string, arguments ...any) string {
+ var envVars string
+ serverCommand := fmt.Sprintf(command, arguments...)
+ if useEnvVars {
+ envVars = c.getEnvVarsAsCliOption()
+ } else {
+ envVars = ""
+ }
+ containerExecCommand := fmt.Sprintf("docker exec %s %s %s", envVars, c.Name, serverCommand)
GinkgoHelper()
c.Suite.Log(containerExecCommand)
byteOutput, err := exechelper.CombinedOutput(containerExecCommand)
@@ -513,7 +541,7 @@ func (c *Container) stop() error {
return nil
}
-func (c *Container) CreateConfig(targetConfigName string, templateName string, values any) {
+func (c *Container) CreateConfigFromTemplate(targetConfigName string, templateName string, values any) {
template := template.Must(template.ParseFiles(templateName))
f, err := os.CreateTemp(logDir, "hst-config")
diff --git a/extras/hs-test/infra/cpu.go b/extras/hs-test/infra/cpu.go
index a1682819a2f..615f8a3f87d 100644
--- a/extras/hs-test/infra/cpu.go
+++ b/extras/hs-test/infra/cpu.go
@@ -4,11 +4,12 @@ import (
"bufio"
"errors"
"fmt"
- . "github.com/onsi/ginkgo/v2"
"os"
"os/exec"
"strconv"
"strings"
+
+ . "github.com/onsi/ginkgo/v2"
)
var CgroupPath = "/sys/fs/cgroup/"
diff --git a/extras/hs-test/infra/hst_suite.go b/extras/hs-test/infra/hst_suite.go
index ed8da3fe244..3aeeb24d14e 100644
--- a/extras/hs-test/infra/hst_suite.go
+++ b/extras/hs-test/infra/hst_suite.go
@@ -4,7 +4,6 @@ import (
"bufio"
"flag"
"fmt"
- "github.com/edwarnicke/exechelper"
"io"
"log"
"net/http"
@@ -17,6 +16,8 @@ import (
"strings"
"time"
+ "github.com/edwarnicke/exechelper"
+
containerTypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/onsi/gomega/gmeasure"
@@ -40,8 +41,9 @@ var IsDebugBuild = flag.Bool("debug_build", false, "some paths are different wit
var UseCpu0 = flag.Bool("cpu0", false, "use cpu0")
var IsLeakCheck = flag.Bool("leak_check", false, "run leak-check tests")
var ParallelTotal = flag.Lookup("ginkgo.parallel.total")
+var DryRun = flag.Bool("dryrun", false, "set up containers but don't run tests")
var NumaAwareCpuAlloc bool
-var SuiteTimeout time.Duration
+var TestTimeout time.Duration
type HstSuite struct {
Containers map[string]*Container
@@ -61,6 +63,18 @@ type HstSuite struct {
Docker *client.Client
}
+type colors struct {
+ grn string
+ pur string
+ rst string
+}
+
+var Colors = colors{
+ grn: "\033[32m",
+ pur: "\033[35m",
+ rst: "\033[0m",
+}
+
// used for colorful ReportEntry
type StringerStruct struct {
Label string
@@ -103,8 +117,8 @@ func (s *HstSuite) newDockerClient() {
func (s *HstSuite) SetupSuite() {
s.CreateLogger()
+ s.Log("[* SUITE SETUP]")
s.newDockerClient()
- s.Log("Suite Setup")
RegisterFailHandler(func(message string, callerSkip ...int) {
s.HstFail()
Fail(message, callerSkip...)
@@ -138,21 +152,28 @@ func (s *HstSuite) AddCpuContext(cpuCtx *CpuContext) {
func (s *HstSuite) TearDownSuite() {
defer s.LogFile.Close()
defer s.Docker.Close()
- s.Log("Suite Teardown")
+ if *IsPersistent || *DryRun {
+ return
+ }
+ s.Log("[* SUITE TEARDOWN]")
s.UnconfigureNetworkTopology()
}
func (s *HstSuite) TearDownTest() {
- s.Log("Test Teardown")
- if *IsPersistent {
+ s.Log("[* TEST TEARDOWN]")
+ if *IsPersistent || *DryRun {
return
}
- s.WaitForCoreDump()
+ coreDump := s.WaitForCoreDump()
s.ResetContainers()
if s.Ip4AddrAllocator != nil {
s.Ip4AddrAllocator.DeleteIpAddresses()
}
+
+ if coreDump {
+ Fail("VPP crashed")
+ }
}
func (s *HstSuite) SkipIfUnconfiguring() {
@@ -162,7 +183,7 @@ func (s *HstSuite) SkipIfUnconfiguring() {
}
func (s *HstSuite) SetupTest() {
- s.Log("Test Setup")
+ s.Log("[* TEST SETUP]")
s.StartedContainers = s.StartedContainers[:0]
s.SkipIfUnconfiguring()
s.SetupContainers()
@@ -289,6 +310,10 @@ func (s *HstSuite) AssertHttpBody(resp *http.Response, expectedBody string, msgA
ExpectWithOffset(2, resp).To(HaveHTTPBody(expectedBody), msgAndArgs...)
}
+func (s *HstSuite) AssertChannelClosed(timeout time.Duration, channel chan error) {
+ EventuallyWithOffset(2, channel).WithTimeout(timeout).Should(BeClosed())
+}
+
func (s *HstSuite) CreateLogger() {
suiteName := s.GetCurrentSuiteName()
var err error
@@ -301,13 +326,20 @@ func (s *HstSuite) CreateLogger() {
// Logs to files by default, logs to stdout when VERBOSE=true with GinkgoWriter
// to keep console tidy
-func (s *HstSuite) Log(arg any) {
- logs := strings.Split(fmt.Sprint(arg), "\n")
+func (s *HstSuite) Log(log any, arg ...any) {
+ var logStr string
+ if len(arg) == 0 {
+ logStr = fmt.Sprint(log)
+ } else {
+ logStr = fmt.Sprintf(fmt.Sprint(log), arg...)
+ }
+ logs := strings.Split(logStr, "\n")
+
for _, line := range logs {
s.Logger.Println(line)
}
if *IsVerbose {
- GinkgoWriter.Println(arg)
+ GinkgoWriter.Println(logStr)
}
}
@@ -321,33 +353,24 @@ func (s *HstSuite) SkipIfMultiWorker(args ...any) {
}
}
-func (s *HstSuite) SkipIfNotEnoughAvailableCpus() bool {
- var MaxRequestedCpu int
+func (s *HstSuite) SkipIfNotEnoughAvailableCpus() {
+ var maxRequestedCpu int
+ availableCpus := len(s.CpuAllocator.cpus) - 1
- if s.CpuAllocator.runningInCi {
- MaxRequestedCpu = ((s.CpuAllocator.buildNumber + 1) * s.CpuAllocator.maxContainerCount * s.CpuCount)
- } else {
- MaxRequestedCpu = (GinkgoParallelProcess() * s.CpuAllocator.maxContainerCount * s.CpuCount)
+ if *UseCpu0 {
+ availableCpus++
}
- if len(s.CpuAllocator.cpus)-1 < MaxRequestedCpu {
- s.Skip(fmt.Sprintf("test case cannot allocate requested cpus (%d cpus * %d containers)", s.CpuCount, s.CpuAllocator.maxContainerCount))
+ if s.CpuAllocator.runningInCi {
+ maxRequestedCpu = ((s.CpuAllocator.buildNumber + 1) * s.CpuAllocator.maxContainerCount * s.CpuCount)
+ } else {
+ maxRequestedCpu = (GinkgoParallelProcess() * s.CpuAllocator.maxContainerCount * s.CpuCount)
}
- return true
-}
-
-func (s *HstSuite) SkipUnlessExtendedTestsBuilt() {
- imageName := "hs-test/nginx-http3"
-
- cmd := exec.Command("docker", "images", imageName)
- byteOutput, err := cmd.CombinedOutput()
- if err != nil {
- s.Log("error while searching for docker image")
- return
- }
- if !strings.Contains(string(byteOutput), imageName) {
- s.Skip("extended tests not built")
+ if availableCpus < maxRequestedCpu {
+ s.Skip(fmt.Sprintf("Test case cannot allocate requested cpus "+
+ "(%d cpus * %d containers, %d available). Try using 'CPU0=true'",
+ s.CpuCount, s.CpuAllocator.maxContainerCount, availableCpus))
}
}
@@ -357,19 +380,19 @@ func (s *HstSuite) SkipUnlessLeakCheck() {
}
}
-func (s *HstSuite) WaitForCoreDump() {
+func (s *HstSuite) WaitForCoreDump() bool {
var filename string
dir, err := os.Open(s.getLogDirPath())
if err != nil {
s.Log(err)
- return
+ return false
}
defer dir.Close()
files, err := dir.Readdirnames(0)
if err != nil {
s.Log(err)
- return
+ return false
}
for _, file := range files {
if strings.Contains(file, "core") {
@@ -386,7 +409,7 @@ func (s *HstSuite) WaitForCoreDump() {
fileInfo, err := os.Stat(corePath)
if err != nil {
s.Log("Error while reading file info: " + fmt.Sprint(err))
- return
+ return true
}
currSize := fileInfo.Size()
s.Log(fmt.Sprintf("Waiting %ds/%ds...", i, timeout))
@@ -413,10 +436,11 @@ func (s *HstSuite) WaitForCoreDump() {
s.Log(err)
}
}
- return
+ return true
}
}
}
+ return false
}
func (s *HstSuite) ResetContainers() {
@@ -480,6 +504,13 @@ func (s *HstSuite) LoadContainerTopology(topologyName string) {
}
s.Containers[newContainer.Name] = newContainer
}
+
+ if *DryRun {
+ s.Log(Colors.pur + "* Containers used by this suite (some might already be running):" + Colors.rst)
+ for name := range s.Containers {
+ s.Log("%sdocker start %s && docker exec -it %s bash%s", Colors.pur, name, name, Colors.rst)
+ }
+ }
}
func (s *HstSuite) LoadNetworkTopology(topologyName string) {
@@ -567,14 +598,18 @@ func (s *HstSuite) ConfigureNetworkTopology(topologyName string) {
}
func (s *HstSuite) UnconfigureNetworkTopology() {
- if *IsPersistent {
- return
- }
for _, nc := range s.NetConfigs {
nc.unconfigure()
}
}
+func (s *HstSuite) LogStartedContainers() {
+ s.Log("%s* Started containers:%s", Colors.grn, Colors.rst)
+ for _, container := range s.StartedContainers {
+ s.Log(Colors.grn + container.Name + Colors.rst)
+ }
+}
+
func (s *HstSuite) GetTestId() string {
testName := s.GetCurrentTestName()
diff --git a/extras/hs-test/infra/suite_cpu_pinning.go b/extras/hs-test/infra/suite_cpu_pinning.go
index e829efa950b..57efbe7f4f0 100644
--- a/extras/hs-test/infra/suite_cpu_pinning.go
+++ b/extras/hs-test/infra/suite_cpu_pinning.go
@@ -2,10 +2,11 @@ package hst
import (
"fmt"
- . "github.com/onsi/ginkgo/v2"
"reflect"
"runtime"
"strings"
+
+ . "github.com/onsi/ginkgo/v2"
)
var cpuPinningTests = map[string][]func(s *CpuPinningSuite){}
@@ -41,6 +42,11 @@ func (s *CpuPinningSuite) SetupTest() {
container := s.GetContainerByName(SingleTopoContainerVpp)
vpp, err := container.newVppInstance(container.AllocatedCpus)
s.AssertNotNil(vpp, fmt.Sprint(err))
+
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Skip("Dry run mode = true")
+ }
}
func (s *CpuPinningSuite) TearDownTest() {
@@ -77,7 +83,7 @@ var _ = Describe("CpuPinningSuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -106,7 +112,7 @@ var _ = Describe("CpuPinningSuiteSolo", Ordered, ContinueOnFailure, Serial, func
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_envoy_proxy.go b/extras/hs-test/infra/suite_envoy_proxy.go
index 80715214cac..50ffd11898e 100644
--- a/extras/hs-test/infra/suite_envoy_proxy.go
+++ b/extras/hs-test/infra/suite_envoy_proxy.go
@@ -7,10 +7,12 @@ package hst
import (
"fmt"
- . "github.com/onsi/ginkgo/v2"
"reflect"
"runtime"
"strings"
+ "time"
+
+ . "github.com/onsi/ginkgo/v2"
)
const (
@@ -63,12 +65,8 @@ func (s *EnvoyProxySuite) SetupTest() {
vppContainer := s.GetContainerByName(VppContainerName)
vpp, err := vppContainer.newVppInstance(vppContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(vpp, fmt.Sprint(err))
- s.AssertNil(vpp.Start())
clientInterface := s.GetInterfaceByName(ClientTapInterfaceName)
- s.AssertNil(vpp.createTap(clientInterface, 1))
serverInterface := s.GetInterfaceByName(ServerTapInterfaceName)
- s.AssertNil(vpp.createTap(serverInterface, 2))
- vppContainer.Exec("chmod 777 -R %s", vppContainer.GetContainerWorkDir())
// nginx HTTP server
nginxContainer := s.GetTransientContainerByName(NginxServerContainerName)
@@ -85,16 +83,16 @@ func (s *EnvoyProxySuite) SetupTest() {
Port: s.nginxPort,
Timeout: s.maxTimeout,
}
- nginxContainer.CreateConfig(
+ nginxContainer.CreateConfigFromTemplate(
"/nginx.conf",
"./resources/nginx/nginx_server.conf",
nginxSettings,
)
- s.AssertNil(nginxContainer.Start())
// Envoy
envoyContainer := s.GetContainerByName(EnvoyProxyContainerName)
s.AssertNil(envoyContainer.Create())
+
s.proxyPort = 8080
envoySettings := struct {
LogPrefix string
@@ -107,19 +105,35 @@ func (s *EnvoyProxySuite) SetupTest() {
ServerPort: s.nginxPort,
ProxyPort: s.proxyPort,
}
- envoyContainer.CreateConfig(
+ envoyContainer.CreateConfigFromTemplate(
"/etc/envoy/envoy.yaml",
"resources/envoy/proxy.yaml",
envoySettings,
)
- s.AssertNil(envoyContainer.Start())
+
+ s.AssertNil(vpp.Start())
+ // wait for VPP to start
+ time.Sleep(time.Second * 1)
+ s.AssertNil(vpp.createTap(clientInterface, 1))
+ s.AssertNil(vpp.createTap(serverInterface, 2))
+ vppContainer.Exec(false, "chmod 777 -R %s", vppContainer.GetContainerWorkDir())
// Add Ipv4 ARP entry for nginx HTTP server, otherwise first request fail (HTTP error 503)
arp := fmt.Sprintf("set ip neighbor %s %s %s",
serverInterface.Peer.Name(),
serverInterface.Ip4AddressString(),
serverInterface.HwAddress)
+
+ if *DryRun {
+ vpp.AppendToCliConfig(arp)
+ s.LogStartedContainers()
+ s.Log("%s* Proxy IP used in tests: %s:%d%s", Colors.pur, s.ProxyAddr(), s.ProxyPort(), Colors.rst)
+ s.Skip("Dry run mode = true")
+ }
+
vppContainer.VppInstance.Vppctl(arp)
+ s.AssertNil(nginxContainer.Start())
+ s.AssertNil(envoyContainer.Start())
}
func (s *EnvoyProxySuite) TearDownTest() {
@@ -177,7 +191,7 @@ var _ = Describe("EnvoyProxySuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -206,7 +220,7 @@ var _ = Describe("EnvoyProxySuiteSolo", Ordered, ContinueOnFailure, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_iperf_linux.go b/extras/hs-test/infra/suite_iperf_linux.go
index 728429b505f..fb685f9ad96 100644
--- a/extras/hs-test/infra/suite_iperf_linux.go
+++ b/extras/hs-test/infra/suite_iperf_linux.go
@@ -61,7 +61,7 @@ var _ = Describe("IperfSuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -90,7 +90,7 @@ var _ = Describe("IperfSuiteSolo", Ordered, ContinueOnFailure, Serial, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_ldp.go b/extras/hs-test/infra/suite_ldp.go
index 15b45f710ef..6294fab0dd6 100644
--- a/extras/hs-test/infra/suite_ldp.go
+++ b/extras/hs-test/infra/suite_ldp.go
@@ -60,24 +60,34 @@ func (s *LdpSuite) SetupTest() {
serverVpp, err := serverContainer.newVppInstance(serverContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(serverVpp, fmt.Sprint(err))
- s.SetupServerVpp()
-
// ... For client
clientContainer := s.GetContainerByName("client-vpp")
clientVpp, err := clientContainer.newVppInstance(clientContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(clientVpp, fmt.Sprint(err))
- s.setupClientVpp()
-
- serverContainer.AddEnvVar("VCL_CONFIG", serverContainer.GetContainerWorkDir()+"/vcl_srv.conf")
- clientContainer.AddEnvVar("VCL_CONFIG", clientContainer.GetContainerWorkDir()+"/vcl_cln.conf")
+ serverContainer.AddEnvVar("VCL_CONFIG", serverContainer.GetContainerWorkDir()+"/vcl.conf")
+ clientContainer.AddEnvVar("VCL_CONFIG", clientContainer.GetContainerWorkDir()+"/vcl.conf")
for _, container := range s.StartedContainers {
container.AddEnvVar("LD_PRELOAD", "/usr/lib/libvcl_ldpreload.so")
container.AddEnvVar("LDP_DEBUG", "0")
container.AddEnvVar("VCL_DEBUG", "0")
}
+
+ s.CreateVclConfig(serverContainer)
+ s.CreateVclConfig(clientContainer)
+ s.SetupServerVpp(serverContainer)
+ s.setupClientVpp(clientContainer)
+
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Log("\n%s* LD_PRELOAD and VCL_CONFIG server/client paths:", Colors.grn)
+ s.Log("LD_PRELOAD=/usr/lib/libvcl_ldpreload.so")
+ s.Log("VCL_CONFIG=%s/vcl.conf", serverContainer.GetContainerWorkDir())
+ s.Log("VCL_CONFIG=%s/vcl.conf%s\n", clientContainer.GetContainerWorkDir(), Colors.rst)
+ s.Skip("Dry run mode = true")
+ }
}
func (s *LdpSuite) TearDownTest() {
@@ -89,36 +99,35 @@ func (s *LdpSuite) TearDownTest() {
}
-func (s *LdpSuite) SetupServerVpp() {
- var srvVclConf Stanza
- serverContainer := s.GetContainerByName("server-vpp")
- serverVclFileName := serverContainer.GetHostWorkDir() + "/vcl_srv.conf"
- serverVpp := serverContainer.VppInstance
- s.AssertNil(serverVpp.Start())
+func (s *LdpSuite) CreateVclConfig(container *Container) {
+ var vclConf Stanza
+ vclFileName := container.GetHostWorkDir() + "/vcl.conf"
- serverVeth := s.GetInterfaceByName(ServerInterfaceName)
- idx, err := serverVpp.createAfPacket(serverVeth)
- s.AssertNil(err, fmt.Sprint(err))
- s.AssertNotEqual(0, idx)
-
- serverAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default",
- serverContainer.GetContainerWorkDir())
- err = srvVclConf.
+ appSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default",
+ container.GetContainerWorkDir())
+ err := vclConf.
NewStanza("vcl").
Append("rx-fifo-size 4000000").
Append("tx-fifo-size 4000000").
Append("app-scope-local").
Append("app-scope-global").
Append("use-mq-eventfd").
- Append(serverAppSocketApi).Close().
- SaveToFile(serverVclFileName)
+ Append(appSocketApi).Close().
+ SaveToFile(vclFileName)
s.AssertNil(err, fmt.Sprint(err))
}
-func (s *LdpSuite) setupClientVpp() {
- var clnVclConf Stanza
- clientContainer := s.GetContainerByName("client-vpp")
- clientVclFileName := clientContainer.GetHostWorkDir() + "/vcl_cln.conf"
+func (s *LdpSuite) SetupServerVpp(serverContainer *Container) {
+ serverVpp := serverContainer.VppInstance
+ s.AssertNil(serverVpp.Start())
+
+ serverVeth := s.GetInterfaceByName(ServerInterfaceName)
+ idx, err := serverVpp.createAfPacket(serverVeth)
+ s.AssertNil(err, fmt.Sprint(err))
+ s.AssertNotEqual(0, idx)
+}
+
+func (s *LdpSuite) setupClientVpp(clientContainer *Container) {
clientVpp := clientContainer.VppInstance
s.AssertNil(clientVpp.Start())
@@ -126,19 +135,6 @@ func (s *LdpSuite) setupClientVpp() {
idx, err := clientVpp.createAfPacket(clientVeth)
s.AssertNil(err, fmt.Sprint(err))
s.AssertNotEqual(0, idx)
-
- clientAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default",
- clientContainer.GetContainerWorkDir())
- err = clnVclConf.
- NewStanza("vcl").
- Append("rx-fifo-size 4000000").
- Append("tx-fifo-size 4000000").
- Append("app-scope-local").
- Append("app-scope-global").
- Append("use-mq-eventfd").
- Append(clientAppSocketApi).Close().
- SaveToFile(clientVclFileName)
- s.AssertNil(err, fmt.Sprint(err))
}
var _ = Describe("LdpSuite", Ordered, ContinueOnFailure, func() {
@@ -167,7 +163,7 @@ var _ = Describe("LdpSuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -197,7 +193,7 @@ var _ = Describe("LdpSuiteSolo", Ordered, ContinueOnFailure, Serial, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_nginx_proxy.go b/extras/hs-test/infra/suite_nginx_proxy.go
index 75215cfc78d..9d81f70720c 100644
--- a/extras/hs-test/infra/suite_nginx_proxy.go
+++ b/extras/hs-test/infra/suite_nginx_proxy.go
@@ -58,33 +58,13 @@ func (s *NginxProxySuite) SetupTest() {
vppContainer := s.GetContainerByName(VppContainerName)
vpp, err := vppContainer.newVppInstance(vppContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(vpp, fmt.Sprint(err))
- s.AssertNil(vpp.Start())
clientInterface := s.GetInterfaceByName(MirroringClientInterfaceName)
- s.AssertNil(vpp.createTap(clientInterface, 1))
serverInterface := s.GetInterfaceByName(MirroringServerInterfaceName)
- s.AssertNil(vpp.createTap(serverInterface, 2))
// nginx proxy
- nginxProxyContainer := s.GetTransientContainerByName(NginxProxyContainerName)
+ nginxProxyContainer := s.GetContainerByName(NginxProxyContainerName)
s.AssertNil(nginxProxyContainer.Create())
s.proxyPort = 80
- values := struct {
- LogPrefix string
- Proxy string
- Server string
- Port uint16
- }{
- LogPrefix: nginxProxyContainer.Name,
- Proxy: clientInterface.Peer.Ip4AddressString(),
- Server: serverInterface.Ip4AddressString(),
- Port: s.proxyPort,
- }
- nginxProxyContainer.CreateConfig(
- "/nginx.conf",
- "./resources/nginx/nginx_proxy_mirroring.conf",
- values,
- )
- s.AssertNil(nginxProxyContainer.Start())
// nginx HTTP server
nginxServerContainer := s.GetTransientContainerByName(NginxServerContainerName)
@@ -98,14 +78,24 @@ func (s *NginxProxySuite) SetupTest() {
Address: serverInterface.Ip4AddressString(),
Timeout: s.maxTimeout,
}
- nginxServerContainer.CreateConfig(
+ nginxServerContainer.CreateConfigFromTemplate(
"/nginx.conf",
"./resources/nginx/nginx_server_mirroring.conf",
nginxSettings,
)
- s.AssertNil(nginxServerContainer.Start())
- vpp.WaitForApp("nginx-", 5)
+ s.AssertNil(vpp.Start())
+ s.AssertNil(vpp.createTap(clientInterface, 1))
+ s.AssertNil(vpp.createTap(serverInterface, 2))
+
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Log("%s* Proxy IP used in tests: %s:%d%s", Colors.pur, s.ProxyAddr(), s.ProxyPort(), Colors.rst)
+ s.Skip("Dry run mode = true")
+ }
+
+ s.AssertNil(nginxProxyContainer.Start())
+ s.AssertNil(nginxServerContainer.Start())
}
func (s *NginxProxySuite) TearDownTest() {
@@ -116,6 +106,35 @@ func (s *NginxProxySuite) TearDownTest() {
s.HstSuite.TearDownTest()
}
+func (s *NginxProxySuite) CreateNginxProxyConfig(container *Container, multiThreadWorkers bool) {
+ clientInterface := s.GetInterfaceByName(MirroringClientInterfaceName)
+ serverInterface := s.GetInterfaceByName(MirroringServerInterfaceName)
+ var workers uint8
+ if multiThreadWorkers {
+ workers = 2
+ } else {
+ workers = 1
+ }
+ values := struct {
+ Workers uint8
+ LogPrefix string
+ Proxy string
+ Server string
+ Port uint16
+ }{
+ Workers: workers,
+ LogPrefix: container.Name,
+ Proxy: clientInterface.Peer.Ip4AddressString(),
+ Server: serverInterface.Ip4AddressString(),
+ Port: s.proxyPort,
+ }
+ container.CreateConfigFromTemplate(
+ "/nginx.conf",
+ "./resources/nginx/nginx_proxy_mirroring.conf",
+ values,
+ )
+}
+
func (s *NginxProxySuite) ProxyPort() uint16 {
return s.proxyPort
}
@@ -132,6 +151,31 @@ func (s *NginxProxySuite) CurlDownloadResource(uri string) {
s.AssertNotContains(log, "Operation timed out")
}
+func (s *NginxProxySuite) AddVclConfig(container *Container, multiThreadWorkers bool) {
+ var vclConf Stanza
+ vclFileName := container.GetHostWorkDir() + "/vcl.conf"
+
+ appSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default",
+ container.GetContainerWorkDir())
+
+ vclConf.
+ NewStanza("vcl").
+ Append("heapsize 64M").
+ Append("rx-fifo-size 4000000").
+ Append("tx-fifo-size 4000000").
+ Append("segment-size 4000000000").
+ Append("add-segment-size 4000000000").
+ Append("event-queue-size 100000").
+ Append("use-mq-eventfd").
+ Append(appSocketApi)
+ if multiThreadWorkers {
+ vclConf.Append("multi-thread-workers")
+ }
+
+ err := vclConf.Close().SaveToFile(vclFileName)
+ s.AssertNil(err, fmt.Sprint(err))
+}
+
var _ = Describe("NginxProxySuite", Ordered, ContinueOnFailure, func() {
var s NginxProxySuite
BeforeAll(func() {
@@ -156,7 +200,7 @@ var _ = Describe("NginxProxySuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -185,7 +229,7 @@ var _ = Describe("NginxProxySuiteSolo", Ordered, ContinueOnFailure, Serial, func
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_no_topo.go b/extras/hs-test/infra/suite_no_topo.go
index 9b4998a77a1..068c43b14d0 100644
--- a/extras/hs-test/infra/suite_no_topo.go
+++ b/extras/hs-test/infra/suite_no_topo.go
@@ -1,6 +1,7 @@
package hst
import (
+ "fmt"
"reflect"
"runtime"
"strings"
@@ -12,6 +13,7 @@ const (
SingleTopoContainerVpp = "vpp"
SingleTopoContainerNginx = "nginx"
TapInterfaceName = "htaphost"
+ NginxHttp3ContainerName = "nginx-http3"
)
var noTopoTests = map[string][]func(s *NoTopoSuite){}
@@ -53,11 +55,66 @@ func (s *NoTopoSuite) SetupTest() {
container := s.GetContainerByName(SingleTopoContainerVpp)
vpp, _ := container.newVppInstance(container.AllocatedCpus, sessionConfig)
- s.AssertNil(vpp.Start())
+ s.AssertNil(vpp.Start())
tapInterface := s.GetInterfaceByName(TapInterfaceName)
-
s.AssertNil(vpp.createTap(tapInterface), "failed to create tap interface")
+
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Skip("Dry run mode = true")
+ }
+}
+
+func (s *NoTopoSuite) TearDownTest() {
+ if CurrentSpecReport().Failed() {
+ s.CollectNginxLogs(NginxHttp3ContainerName)
+ }
+ s.HstSuite.TearDownTest()
+}
+
+func (s *NoTopoSuite) CreateNginxConfig(container *Container, multiThreadWorkers bool) {
+ var workers uint8
+ if multiThreadWorkers {
+ workers = 2
+ } else {
+ workers = 1
+ }
+ values := struct {
+ Workers uint8
+ }{
+ Workers: workers,
+ }
+ container.CreateConfigFromTemplate(
+ "/nginx.conf",
+ "./resources/nginx/nginx.conf",
+ values,
+ )
+}
+
+func (s *NoTopoSuite) AddNginxVclConfig(multiThreadWorkers bool) {
+ nginxCont := s.GetContainerByName(SingleTopoContainerNginx)
+ vclFileName := nginxCont.GetHostWorkDir() + "/vcl.conf"
+ appSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default",
+ nginxCont.GetContainerWorkDir())
+
+ var vclConf Stanza
+ vclConf.
+ NewStanza("vcl").
+ Append("heapsize 64M").
+ Append("rx-fifo-size 4000000").
+ Append("tx-fifo-size 4000000").
+ Append("segment-size 4000000000").
+ Append("add-segment-size 4000000000").
+ Append("event-queue-size 100000").
+ Append("use-mq-eventfd").
+ Append(appSocketApi)
+ if multiThreadWorkers {
+ vclConf.Append("multi-thread-workers")
+ }
+
+ err := vclConf.Close().SaveToFile(vclFileName)
+ s.AssertNil(err, fmt.Sprint(err))
}
func (s *NoTopoSuite) VppAddr() string {
@@ -72,6 +129,19 @@ func (s *NoTopoSuite) HostAddr() string {
return s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
}
+func (s *NoTopoSuite) CreateNginxHttp3Config(container *Container) {
+ nginxSettings := struct {
+ LogPrefix string
+ }{
+ LogPrefix: container.Name,
+ }
+ container.CreateConfigFromTemplate(
+ "/nginx.conf",
+ "./resources/nginx/nginx_http3.conf",
+ nginxSettings,
+ )
+}
+
var _ = Describe("NoTopoSuite", Ordered, ContinueOnFailure, func() {
var s NoTopoSuite
BeforeAll(func() {
@@ -96,7 +166,7 @@ var _ = Describe("NoTopoSuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -125,7 +195,7 @@ var _ = Describe("NoTopoSuiteSolo", Ordered, ContinueOnFailure, Serial, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_ns.go b/extras/hs-test/infra/suite_ns.go
deleted file mode 100644
index 601ec22a8a9..00000000000
--- a/extras/hs-test/infra/suite_ns.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package hst
-
-import (
- "fmt"
- "reflect"
- "runtime"
- "strings"
-
- . "github.com/onsi/ginkgo/v2"
-)
-
-// These correspond to names used in yaml config
-const (
- ClientInterface = "hclnvpp"
- ServerInterface = "hsrvvpp"
-)
-
-var nsTests = map[string][]func(s *NsSuite){}
-var nsSoloTests = map[string][]func(s *NsSuite){}
-
-type NsSuite struct {
- HstSuite
-}
-
-func RegisterNsTests(tests ...func(s *NsSuite)) {
- nsTests[getTestFilename()] = tests
-}
-func RegisterNsSoloTests(tests ...func(s *NsSuite)) {
- nsSoloTests[getTestFilename()] = tests
-}
-
-func (s *NsSuite) SetupSuite() {
- s.HstSuite.SetupSuite()
- s.ConfigureNetworkTopology("ns")
- s.LoadContainerTopology("ns")
-}
-
-func (s *NsSuite) SetupTest() {
- s.HstSuite.SetupTest()
-
- // Setup test conditions
- var sessionConfig Stanza
- sessionConfig.
- NewStanza("session").
- Append("enable").
- Append("use-app-socket-api").
- Append("evt_qs_memfd_seg").
- Append("event-queue-length 100000")
-
- if strings.Contains(CurrentSpecReport().LeafNodeText, "InterruptMode") {
- sessionConfig.Append("use-private-rx-mqs").Close()
- } else {
- sessionConfig.Close()
- }
-
- container := s.GetContainerByName("vpp")
- vpp, _ := container.newVppInstance(container.AllocatedCpus, sessionConfig)
- s.AssertNil(vpp.Start())
-
- idx, err := vpp.createAfPacket(s.GetInterfaceByName(ServerInterface))
- s.AssertNil(err, fmt.Sprint(err))
- s.AssertNotEqual(0, idx)
-
- idx, err = vpp.createAfPacket(s.GetInterfaceByName(ClientInterface))
- s.AssertNil(err, fmt.Sprint(err))
- s.AssertNotEqual(0, idx)
-
- container.Exec("chmod 777 -R %s", container.GetContainerWorkDir())
-}
-
-var _ = Describe("NsSuite", Ordered, ContinueOnFailure, func() {
- var s NsSuite
- BeforeAll(func() {
- s.SetupSuite()
- })
- BeforeEach(func() {
- s.SetupTest()
- })
- AfterAll(func() {
- s.TearDownSuite()
- })
- AfterEach(func() {
- s.TearDownTest()
- })
-
- for filename, tests := range nsTests {
- for _, test := range tests {
- test := test
- pc := reflect.ValueOf(test).Pointer()
- funcValue := runtime.FuncForPC(pc)
- testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2]
- It(testName, func(ctx SpecContext) {
- s.Log(testName + ": BEGIN")
- test(&s)
- }, SpecTimeout(SuiteTimeout))
- }
- }
-})
-
-var _ = Describe("NsSuiteSolo", Ordered, ContinueOnFailure, Serial, func() {
- var s NsSuite
- BeforeAll(func() {
- s.SetupSuite()
- })
- BeforeEach(func() {
- s.SetupTest()
- })
- AfterAll(func() {
- s.TearDownSuite()
- })
- AfterEach(func() {
- s.TearDownTest()
- })
-
- for filename, tests := range nsSoloTests {
- for _, test := range tests {
- test := test
- pc := reflect.ValueOf(test).Pointer()
- funcValue := runtime.FuncForPC(pc)
- testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2]
- It(testName, Label("SOLO"), func(ctx SpecContext) {
- s.Log(testName + ": BEGIN")
- test(&s)
- }, SpecTimeout(SuiteTimeout))
- }
- }
-})
diff --git a/extras/hs-test/infra/suite_veth.go b/extras/hs-test/infra/suite_veth.go
index f7b1c3da7d8..cbbd7ee2694 100644
--- a/extras/hs-test/infra/suite_veth.go
+++ b/extras/hs-test/infra/suite_veth.go
@@ -60,15 +60,18 @@ func (s *VethsSuite) SetupTest() {
serverVpp, err := serverContainer.newVppInstance(serverContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(serverVpp, fmt.Sprint(err))
- s.SetupServerVpp()
-
// ... For client
clientContainer := s.GetContainerByName("client-vpp")
clientVpp, err := clientContainer.newVppInstance(clientContainer.AllocatedCpus, sessionConfig)
s.AssertNotNil(clientVpp, fmt.Sprint(err))
+ s.SetupServerVpp()
s.setupClientVpp()
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Skip("Dry run mode = true")
+ }
}
func (s *VethsSuite) SetupServerVpp() {
@@ -117,7 +120,7 @@ var _ = Describe("VethsSuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -147,7 +150,7 @@ var _ = Describe("VethsSuiteSolo", Ordered, ContinueOnFailure, Serial, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/suite_vpp_proxy.go b/extras/hs-test/infra/suite_vpp_proxy.go
index 21e81e0581e..16c6115bc23 100644
--- a/extras/hs-test/infra/suite_vpp_proxy.go
+++ b/extras/hs-test/infra/suite_vpp_proxy.go
@@ -7,10 +7,11 @@ package hst
import (
"fmt"
- . "github.com/onsi/ginkgo/v2"
"reflect"
"runtime"
"strings"
+
+ . "github.com/onsi/ginkgo/v2"
)
// These correspond to names used in yaml config
@@ -57,11 +58,9 @@ func (s *VppProxySuite) SetupTest() {
vppContainer := s.GetContainerByName(VppProxyContainerName)
vpp, err := vppContainer.newVppInstance(vppContainer.AllocatedCpus)
s.AssertNotNil(vpp, fmt.Sprint(err))
- s.AssertNil(vpp.Start())
+
clientInterface := s.GetInterfaceByName(ClientTapInterfaceName)
- s.AssertNil(vpp.createTap(clientInterface, 1))
serverInterface := s.GetInterfaceByName(ServerTapInterfaceName)
- s.AssertNil(vpp.createTap(serverInterface, 2))
// nginx HTTP server
nginxContainer := s.GetTransientContainerByName(NginxServerContainerName)
@@ -78,12 +77,21 @@ func (s *VppProxySuite) SetupTest() {
Port: s.nginxPort,
Timeout: s.maxTimeout,
}
- nginxContainer.CreateConfig(
+ nginxContainer.CreateConfigFromTemplate(
"/nginx.conf",
"./resources/nginx/nginx_server.conf",
nginxSettings,
)
s.AssertNil(nginxContainer.Start())
+
+ s.AssertNil(vpp.Start())
+ s.AssertNil(vpp.createTap(clientInterface, 1))
+ s.AssertNil(vpp.createTap(serverInterface, 2))
+
+ if *DryRun {
+ s.LogStartedContainers()
+ s.Skip("Dry run mode = true")
+ }
}
func (s *VppProxySuite) TearDownTest() {
@@ -176,7 +184,7 @@ var _ = Describe("VppProxySuite", Ordered, ContinueOnFailure, func() {
It(testName, func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
@@ -205,7 +213,7 @@ var _ = Describe("VppProxySuiteSolo", Ordered, ContinueOnFailure, func() {
It(testName, Label("SOLO"), func(ctx SpecContext) {
s.Log(testName + ": BEGIN")
test(&s)
- }, SpecTimeout(SuiteTimeout))
+ }, SpecTimeout(TestTimeout))
}
}
})
diff --git a/extras/hs-test/infra/utils.go b/extras/hs-test/infra/utils.go
index 25d8519cb8a..30abb6ac715 100644
--- a/extras/hs-test/infra/utils.go
+++ b/extras/hs-test/infra/utils.go
@@ -1,6 +1,7 @@
package hst
import (
+ "crypto/tls"
"errors"
"fmt"
"io"
@@ -86,13 +87,14 @@ func (s *Stanza) SaveToFile(fileName string) error {
}
// NewHttpClient creates [http.Client] with disabled proxy and redirects, it also sets timeout to 30seconds.
-func NewHttpClient() *http.Client {
+func NewHttpClient(timeout time.Duration) *http.Client {
transport := http.DefaultTransport
transport.(*http.Transport).Proxy = nil
transport.(*http.Transport).DisableKeepAlives = true
+ transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{
Transport: transport,
- Timeout: time.Second * 30,
+ Timeout: timeout,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}}
@@ -254,6 +256,7 @@ func (s *HstSuite) StartWget(finished chan error, server_ip, port, query, netNs
netNs)
s.Log(cmd)
o, err := cmd.CombinedOutput()
+ s.Log(string(o))
if err != nil {
finished <- fmt.Errorf("wget error: '%v\n\n%s'", err, o)
return
@@ -269,7 +272,7 @@ func (s *HstSuite) StartServerApp(c *Container, processName string, cmd string,
running chan error, done chan struct{}) {
s.Log("starting server")
- c.ExecServer(cmd)
+ c.ExecServer(true, cmd)
cmd2 := exec.Command("docker", "exec", c.Name, "pidof", processName)
err := cmd2.Run()
if err != nil {
diff --git a/extras/hs-test/infra/vppinstance.go b/extras/hs-test/infra/vppinstance.go
index b3ae995870f..d40fbffe63c 100644
--- a/extras/hs-test/infra/vppinstance.go
+++ b/extras/hs-test/infra/vppinstance.go
@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
- "go.fd.io/govpp/binapi/ethernet_types"
"io"
"net"
"os"
@@ -15,6 +14,8 @@ import (
"syscall"
"time"
+ "go.fd.io/govpp/binapi/ethernet_types"
+
"github.com/edwarnicke/exechelper"
. "github.com/onsi/ginkgo/v2"
"github.com/sirupsen/logrus"
@@ -36,6 +37,7 @@ const vppConfigTemplate = `unix {
coredump-size unlimited
cli-listen %[1]s%[2]s
runtime-dir %[1]s/var/run
+ %[5]s
}
api-trace {
@@ -58,6 +60,7 @@ plugins {
plugin af_packet_plugin.so { enable }
plugin hs_apps_plugin.so { enable }
plugin http_plugin.so { enable }
+ plugin http_unittest_plugin.so { enable }
plugin http_static_plugin.so { enable }
plugin prom_plugin.so { enable }
plugin tlsopenssl_plugin.so { enable }
@@ -121,18 +124,27 @@ func (vpp *VppInstance) getEtcDir() string {
return vpp.Container.GetContainerWorkDir() + "/etc/vpp"
}
+// Appends a string to '[host-work-dir]/cli-config.conf'.
+// Creates the conf file if it doesn't exist. Used for dry-run mode.
+func (vpp *VppInstance) AppendToCliConfig(vppCliConfig string) {
+ f, err := os.OpenFile(vpp.Container.GetHostWorkDir()+"/cli-config.conf", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ vpp.getSuite().AssertNil(err)
+ _, err = f.Write([]byte(vppCliConfig))
+ vpp.getSuite().AssertNil(err)
+ err = f.Close()
+ vpp.getSuite().AssertNil(err)
+}
+
func (vpp *VppInstance) Start() error {
- maxReconnectAttempts := 3
- // Replace default logger in govpp with our own
- govppLogger := logrus.New()
- govppLogger.SetOutput(io.MultiWriter(vpp.getSuite().Logger.Writer(), GinkgoWriter))
- core.SetLogger(govppLogger)
- // Create folders
containerWorkDir := vpp.Container.GetContainerWorkDir()
+ var cliConfig string
+ if *DryRun {
+ cliConfig = fmt.Sprintf("exec %s/cli-config.conf", containerWorkDir)
+ }
- vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getRunDir())
- vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getLogDir())
- vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getEtcDir())
+ vpp.Container.Exec(false, "mkdir --mode=0700 -p "+vpp.getRunDir())
+ vpp.Container.Exec(false, "mkdir --mode=0700 -p "+vpp.getLogDir())
+ vpp.Container.Exec(false, "mkdir --mode=0700 -p "+vpp.getEtcDir())
// Create startup.conf inside the container
configContent := fmt.Sprintf(
@@ -141,6 +153,7 @@ func (vpp *VppInstance) Start() error {
defaultCliSocketFilePath,
defaultApiSocketFilePath,
defaultLogFilePath,
+ cliConfig,
)
configContent += vpp.generateVPPCpuConfig()
for _, c := range vpp.AdditionalConfig {
@@ -153,7 +166,20 @@ func (vpp *VppInstance) Start() error {
cliContent := "#!/usr/bin/bash\nvppctl -s " + vpp.getRunDir() + "/cli.sock"
vppcliFileName := "/usr/bin/vppcli"
vpp.Container.CreateFile(vppcliFileName, cliContent)
- vpp.Container.Exec("chmod 0755 " + vppcliFileName)
+ vpp.Container.Exec(false, "chmod 0755 "+vppcliFileName)
+
+ if *DryRun {
+ vpp.getSuite().Log("%s* Commands to start VPP and VPPCLI:", Colors.pur)
+ vpp.getSuite().Log("vpp -c %s/startup.conf", vpp.getEtcDir())
+ vpp.getSuite().Log("vppcli (= vppctl -s %s/cli.sock)%s\n", vpp.getRunDir(), Colors.rst)
+ return nil
+ }
+
+ maxReconnectAttempts := 3
+ // Replace default logger in govpp with our own
+ govppLogger := logrus.New()
+ govppLogger.SetOutput(io.MultiWriter(vpp.getSuite().Logger.Writer(), GinkgoWriter))
+ core.SetLogger(govppLogger)
vpp.getSuite().Log("starting vpp")
if *IsVppDebug {
@@ -167,7 +193,7 @@ func (vpp *VppInstance) Start() error {
cont <- true
}()
- vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"")
+ vpp.Container.ExecServer(false, "su -c \"vpp -c "+startupFileName+" &> /proc/1/fd/1\"")
fmt.Println("run following command in different terminal:")
fmt.Println("docker exec -it " + vpp.Container.Name + " gdb -ex \"attach $(docker exec " + vpp.Container.Name + " pidof vpp)\"")
fmt.Println("Afterwards press CTRL+\\ to continue")
@@ -175,7 +201,7 @@ func (vpp *VppInstance) Start() error {
fmt.Println("continuing...")
} else {
// Start VPP
- vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"")
+ vpp.Container.ExecServer(false, "su -c \"vpp -c "+startupFileName+" &> /proc/1/fd/1\"")
}
vpp.getSuite().Log("connecting to vpp")
@@ -255,6 +281,23 @@ func (vpp *VppInstance) WaitForApp(appName string, timeout int) {
func (vpp *VppInstance) createAfPacket(
veth *NetInterface,
) (interface_types.InterfaceIndex, error) {
+ if *DryRun {
+ if ip4Address, err := veth.Ip4AddrAllocator.NewIp4InterfaceAddress(veth.Peer.NetworkNumber); err == nil {
+ veth.Ip4Address = ip4Address
+ } else {
+ return 0, err
+ }
+ vppCliConfig := fmt.Sprintf(
+ "create host-interface name %s\n"+
+ "set int state host-%s up\n"+
+ "set int ip addr host-%s %s\n",
+ veth.Name(),
+ veth.Name(),
+ veth.Name(), veth.Ip4Address)
+ vpp.AppendToCliConfig(vppCliConfig)
+ vpp.getSuite().Log("%s* Interface added:\n%s%s", Colors.grn, vppCliConfig, Colors.rst)
+ return 1, nil
+ }
createReq := &af_packet.AfPacketCreateV3{
Mode: 1,
UseRandomHwAddr: true,
@@ -381,14 +424,28 @@ func (vpp *VppInstance) addAppNamespace(
return nil
}
-func (vpp *VppInstance) createTap(
- tap *NetInterface,
- tapId ...uint32,
-) error {
+func (vpp *VppInstance) createTap(tap *NetInterface, tapId ...uint32) error {
var id uint32 = 1
if len(tapId) > 0 {
id = tapId[0]
}
+
+ if *DryRun {
+ vppCliConfig := fmt.Sprintf("create tap id %d host-if-name %s host-ip4-addr %s\n"+
+ "set int ip addr tap%d %s\n"+
+ "set int state tap%d up\n",
+ id,
+ tap.name,
+ tap.Ip4Address,
+ id,
+ tap.Peer.Ip4Address,
+ id,
+ )
+ vpp.AppendToCliConfig(vppCliConfig)
+ vpp.getSuite().Log("%s* Interface added:\n%s%s", Colors.grn, vppCliConfig, Colors.rst)
+ return nil
+ }
+
createTapReq := &tapv2.TapCreateV3{
ID: id,
HostIfNameSet: true,
diff --git a/extras/hs-test/iperf_linux_test.go b/extras/hs-test/iperf_linux_test.go
index 14422fe5efa..b2b52a758ed 100644
--- a/extras/hs-test/iperf_linux_test.go
+++ b/extras/hs-test/iperf_linux_test.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "time"
. "fd.io/hs-test/infra"
. "github.com/onsi/ginkgo/v2"
@@ -41,8 +42,6 @@ func IperfLinuxTest(s *IperfSuite) {
" -u -l 1460 -b 10g -p " + s.GetPortFromPpid()
s.StartClientApp(clientContainer, cmd, clnCh, clnRes)
}()
-
+ s.AssertChannelClosed(time.Minute*3, clnCh)
s.Log(<-clnRes)
- err = <-clnCh
- s.AssertNil(err, "err: '%s'", err)
}
diff --git a/extras/hs-test/ldp_test.go b/extras/hs-test/ldp_test.go
index 03636b11191..e72fac4fbba 100644
--- a/extras/hs-test/ldp_test.go
+++ b/extras/hs-test/ldp_test.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "time"
. "fd.io/hs-test/infra"
. "github.com/onsi/ginkgo/v2"
@@ -24,6 +25,10 @@ func LDPreloadIperfVppTest(s *LdpSuite) {
clnCh := make(chan error)
clnRes := make(chan string, 1)
+ defer func() {
+ stopServerCh <- struct{}{}
+ }()
+
go func() {
defer GinkgoRecover()
cmd := "iperf3 -4 -s -p " + s.GetPortFromPpid()
@@ -39,14 +44,9 @@ func LDPreloadIperfVppTest(s *LdpSuite) {
cmd := "iperf3 -c " + serverVethAddress + " -u -l 1460 -b 10g -p " + s.GetPortFromPpid()
s.StartClientApp(clientContainer, cmd, clnCh, clnRes)
}()
- s.Log(<-clnRes)
-
- // wait for client's result
- err = <-clnCh
- s.AssertNil(err, fmt.Sprint(err))
- // stop server
- stopServerCh <- struct{}{}
+ s.AssertChannelClosed(time.Minute*3, clnCh)
+ s.Log(<-clnRes)
}
func RedisBenchmarkTest(s *LdpSuite) {
@@ -61,6 +61,10 @@ func RedisBenchmarkTest(s *LdpSuite) {
clnCh := make(chan error)
clnRes := make(chan string, 1)
+ defer func() {
+ doneSrv <- struct{}{}
+ }()
+
go func() {
defer GinkgoRecover()
cmd := "redis-server --daemonize yes --protected-mode no --bind " + serverVethAddress
@@ -79,12 +83,10 @@ func RedisBenchmarkTest(s *LdpSuite) {
cmd = "redis-benchmark --threads " + fmt.Sprint(*NConfiguredCpus) + "-h " + serverVethAddress
}
s.StartClientApp(clientContainer, cmd, clnCh, clnRes)
+
}()
+ // 4.5 minutes
+ s.AssertChannelClosed(time.Second*270, clnCh)
s.Log(<-clnRes)
- // wait for client's result
- err = <-clnCh
- s.AssertNil(err, fmt.Sprint(err))
- // stop server
- doneSrv <- struct{}{}
}
diff --git a/extras/hs-test/mem_leak_test.go b/extras/hs-test/mem_leak_test.go
index 76966ae968a..0d8831d2bbc 100644
--- a/extras/hs-test/mem_leak_test.go
+++ b/extras/hs-test/mem_leak_test.go
@@ -1,8 +1,9 @@
package main
import (
- . "fd.io/hs-test/infra"
"fmt"
+
+ . "fd.io/hs-test/infra"
)
func init() {
diff --git a/extras/hs-test/nginx_test.go b/extras/hs-test/nginx_test.go
index fa6afda58fc..7a6f5b3c182 100644
--- a/extras/hs-test/nginx_test.go
+++ b/extras/hs-test/nginx_test.go
@@ -1,24 +1,27 @@
package main
import (
- . "fd.io/hs-test/infra"
"fmt"
- . "github.com/onsi/ginkgo/v2"
"os"
"strings"
+
+ . "fd.io/hs-test/infra"
+ . "github.com/onsi/ginkgo/v2"
)
func init() {
RegisterNoTopoTests(NginxHttp3Test, NginxAsServerTest, NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest,
NginxPerfCpsInterruptModeTest, NginxPerfRpsInterruptModeTest, NginxPerfWrkInterruptModeTest)
+ RegisterNoTopoSoloTests(NginxPerfRpsMultiThreadTest, NginxPerfCpsMultiThreadTest)
}
func NginxHttp3Test(s *NoTopoSuite) {
- s.SkipUnlessExtendedTestsBuilt()
-
query := "index.html"
- nginxCont := s.GetContainerByName("nginx-http3")
- nginxCont.Run()
+ nginxCont := s.GetContainerByName(NginxHttp3ContainerName)
+
+ nginxCont.Create()
+ s.CreateNginxHttp3Config(nginxCont)
+ nginxCont.Start()
vpp := s.GetContainerByName("vpp").VppInstance
vpp.WaitForApp("nginx-", 5)
@@ -29,17 +32,23 @@ func NginxHttp3Test(s *NoTopoSuite) {
args := fmt.Sprintf("curl --noproxy '*' --local-port 55444 --http3-only -k https://%s:8443/%s", serverAddress, query)
curlCont.ExtraRunningArgs = args
curlCont.Run()
- o, err := curlCont.GetOutput()
- s.Log(o)
- s.AssertEmpty(err)
- s.AssertContains(o, "<http>", "<http> not found in the result!")
+ body, stats := curlCont.GetOutput()
+ s.Log(body)
+ s.Log(stats)
+ s.AssertNotContains(stats, "refused")
+ s.AssertContains(stats, "100")
+ s.AssertContains(body, "<http>", "<http> not found in the result!")
}
+
func NginxAsServerTest(s *NoTopoSuite) {
query := "return_ok"
finished := make(chan error, 1)
nginxCont := s.GetContainerByName("nginx")
- nginxCont.Run()
+ nginxCont.Create()
+ s.CreateNginxConfig(nginxCont, false)
+ s.AddNginxVclConfig(false)
+ nginxCont.Start()
vpp := s.GetContainerByName("vpp").VppInstance
vpp.WaitForApp("nginx-", 5)
@@ -64,7 +73,7 @@ func parseString(s, pattern string) string {
return ""
}
-func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
+func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string, multiThreadWorkers bool) error {
nRequests := 1000000
nClients := 1000
@@ -73,7 +82,10 @@ func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
vpp := s.GetContainerByName("vpp").VppInstance
nginxCont := s.GetContainerByName(SingleTopoContainerNginx)
- nginxCont.Run()
+ nginxCont.Create()
+ s.AddNginxVclConfig(multiThreadWorkers)
+ s.CreateNginxConfig(nginxCont, multiThreadWorkers)
+ nginxCont.Start()
vpp.WaitForApp("nginx-", 5)
if ab_or_wrk == "ab" {
@@ -88,6 +100,7 @@ func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
args += " -r"
args += " http://" + serverAddress + ":80/64B.json"
abCont.ExtraRunningArgs = args
+ s.Log("Test might take up to 2 minutes to finish. Please wait")
abCont.Run()
o, err := abCont.GetOutput()
rps := parseString(o, "Requests per second:")
@@ -113,18 +126,24 @@ func NginxPerfCpsInterruptModeTest(s *NoTopoSuite) {
NginxPerfCpsTest(s)
}
-// unstable with multiple workers
+func NginxPerfCpsMultiThreadTest(s *NoTopoSuite) {
+ s.AssertNil(runNginxPerf(s, "cps", "ab", true))
+}
+
func NginxPerfCpsTest(s *NoTopoSuite) {
- s.SkipIfMultiWorker()
- s.AssertNil(runNginxPerf(s, "cps", "ab"))
+ s.AssertNil(runNginxPerf(s, "cps", "ab", false))
}
func NginxPerfRpsInterruptModeTest(s *NoTopoSuite) {
NginxPerfRpsTest(s)
}
+func NginxPerfRpsMultiThreadTest(s *NoTopoSuite) {
+ s.AssertNil(runNginxPerf(s, "rps", "ab", true))
+}
+
func NginxPerfRpsTest(s *NoTopoSuite) {
- s.AssertNil(runNginxPerf(s, "rps", "ab"))
+ s.AssertNil(runNginxPerf(s, "rps", "ab", false))
}
func NginxPerfWrkInterruptModeTest(s *NoTopoSuite) {
@@ -132,5 +151,5 @@ func NginxPerfWrkInterruptModeTest(s *NoTopoSuite) {
}
func NginxPerfWrkTest(s *NoTopoSuite) {
- s.AssertNil(runNginxPerf(s, "", "wrk"))
+ s.AssertNil(runNginxPerf(s, "", "wrk", false))
}
diff --git a/extras/hs-test/proxy_test.go b/extras/hs-test/proxy_test.go
index 7ec97c76c02..5ca151f6228 100644
--- a/extras/hs-test/proxy_test.go
+++ b/extras/hs-test/proxy_test.go
@@ -1,26 +1,26 @@
package main
import (
- . "fd.io/hs-test/infra"
"fmt"
+
+ . "fd.io/hs-test/infra"
)
func init() {
- RegisterVppProxyTests(VppProxyHttpGetTcpTest, VppProxyHttpGetTlsTest, VppProxyHttpPutTcpTest, VppProxyHttpPutTlsTest)
+ RegisterVppProxyTests(VppProxyHttpGetTcpTest, VppProxyHttpGetTlsTest, VppProxyHttpPutTcpTest, VppProxyHttpPutTlsTest,
+ VppConnectProxyGetTest, VppConnectProxyPutTest)
RegisterEnvoyProxyTests(EnvoyProxyHttpGetTcpTest, EnvoyProxyHttpPutTcpTest)
RegisterNginxProxyTests(NginxMirroringTest)
+ RegisterNginxProxySoloTests(MirrorMultiThreadTest)
}
func configureVppProxy(s *VppProxySuite, proto string, proxyPort uint16) {
vppProxy := s.GetContainerByName(VppProxyContainerName).VppInstance
- output := vppProxy.Vppctl(
- "test proxy server server-uri %s://%s/%d client-uri tcp://%s/%d",
- proto,
- s.VppProxyAddr(),
- proxyPort,
- s.NginxAddr(),
- s.NginxPort(),
- )
+ cmd := fmt.Sprintf("test proxy server fifo-size 512k server-uri %s://%s/%d", proto, s.VppProxyAddr(), proxyPort)
+ if proto != "http" {
+ cmd += fmt.Sprintf(" client-uri tcp://%s/%d", s.NginxAddr(), s.NginxPort())
+ }
+ output := vppProxy.Vppctl(cmd)
s.Log("proxy configured: " + output)
}
@@ -62,9 +62,42 @@ func EnvoyProxyHttpPutTcpTest(s *EnvoyProxySuite) {
s.CurlUploadResource(uri, CurlContainerTestFile)
}
-// broken when CPUS > 1
+func MirrorMultiThreadTest(s *NginxProxySuite) {
+ nginxMirroring(s, true)
+}
+
func NginxMirroringTest(s *NginxProxySuite) {
- s.SkipIfMultiWorker()
+ nginxMirroring(s, false)
+}
+
+func nginxMirroring(s *NginxProxySuite, multiThreadWorkers bool) {
+ nginxProxyContainer := s.GetContainerByName(NginxProxyContainerName)
+ vpp := s.GetContainerByName(VppContainerName).VppInstance
+
+ s.AddVclConfig(nginxProxyContainer, multiThreadWorkers)
+ s.CreateNginxProxyConfig(nginxProxyContainer, multiThreadWorkers)
+ nginxProxyContainer.Start()
+ vpp.WaitForApp("nginx-", 5)
uri := fmt.Sprintf("http://%s:%d/httpTestFile", s.ProxyAddr(), s.ProxyPort())
s.CurlDownloadResource(uri)
}
+
+func VppConnectProxyGetTest(s *VppProxySuite) {
+ var proxyPort uint16 = 8080
+
+ configureVppProxy(s, "http", proxyPort)
+
+ targetUri := fmt.Sprintf("http://%s:%d/httpTestFile", s.NginxAddr(), s.NginxPort())
+ proxyUri := fmt.Sprintf("http://%s:%d", s.VppProxyAddr(), proxyPort)
+ s.CurlDownloadResourceViaTunnel(targetUri, proxyUri)
+}
+
+func VppConnectProxyPutTest(s *VppProxySuite) {
+ var proxyPort uint16 = 8080
+
+ configureVppProxy(s, "http", proxyPort)
+
+ proxyUri := fmt.Sprintf("http://%s:%d", s.VppProxyAddr(), proxyPort)
+ targetUri := fmt.Sprintf("http://%s:%d/upload/testFile", s.NginxAddr(), s.NginxPort())
+ s.CurlUploadResourceViaTunnel(targetUri, proxyUri, CurlContainerTestFile)
+}
diff --git a/extras/hs-test/raw_session_test.go b/extras/hs-test/raw_session_test.go
index 438b7ba03a5..822ee5c68e3 100644
--- a/extras/hs-test/raw_session_test.go
+++ b/extras/hs-test/raw_session_test.go
@@ -29,7 +29,7 @@ func testVppEcho(s *VethsSuite, proto string) {
" use-app-socket-api" +
" uri " + uri
s.Log(serverCommand)
- echoSrvContainer.ExecServer(serverCommand)
+ echoSrvContainer.ExecServer(true, serverCommand)
echoClnContainer := s.GetContainerByName("client-app")
@@ -37,6 +37,6 @@ func testVppEcho(s *VethsSuite, proto string) {
" socket-name " + echoClnContainer.GetContainerWorkDir() + "/var/run/app_ns_sockets/default" +
" use-app-socket-api uri " + uri
s.Log(clientCommand)
- o := echoClnContainer.Exec(clientCommand)
+ o := echoClnContainer.Exec(true, clientCommand)
s.Log(o)
}
diff --git a/extras/hs-test/resources/nginx/nginx.conf b/extras/hs-test/resources/nginx/nginx.conf
index 99073aab1ab..956a13138eb 100644
--- a/extras/hs-test/resources/nginx/nginx.conf
+++ b/extras/hs-test/resources/nginx/nginx.conf
@@ -1,6 +1,6 @@
master_process on;
worker_rlimit_nofile 10240;
-worker_processes 2;
+worker_processes {{.Workers}};
daemon off;
events {
diff --git a/extras/hs-test/resources/nginx/nginx_http3.conf b/extras/hs-test/resources/nginx/nginx_http3.conf
index 2a01f714111..e048b17044b 100644
--- a/extras/hs-test/resources/nginx/nginx_http3.conf
+++ b/extras/hs-test/resources/nginx/nginx_http3.conf
@@ -2,6 +2,8 @@ master_process on;
worker_processes 2;
daemon off;
+error_log /tmp/nginx/{{.LogPrefix}}-error.log info;
+
events {
use epoll;
accept_mutex off;
@@ -12,12 +14,11 @@ http {
quic_gso on;
quic_retry on;
- access_log logs/access.log;
+ access_log /tmp/nginx/{{.LogPrefix}}-access.log;
keepalive_timeout 300s;
sendfile on;
server {
listen 0.0.0.0:8443 quic;
- #listen 0.0.0.0:8443 ssl;
root /usr/share/nginx;
ssl_certificate /etc/nginx/ssl/localhost.crt;
ssl_certificate_key /etc/nginx/ssl/localhost.key;
diff --git a/extras/hs-test/resources/nginx/nginx_proxy_mirroring.conf b/extras/hs-test/resources/nginx/nginx_proxy_mirroring.conf
index 7f6b09c6050..d834a27288a 100644
--- a/extras/hs-test/resources/nginx/nginx_proxy_mirroring.conf
+++ b/extras/hs-test/resources/nginx/nginx_proxy_mirroring.conf
@@ -1,5 +1,5 @@
master_process on;
-worker_processes 4;
+worker_processes {{.Workers}};
worker_rlimit_nofile 102400;
daemon off;
diff --git a/extras/hs-test/resources/nginx/vcl.conf b/extras/hs-test/resources/nginx/vcl.conf
index cfcd5d2e959..27699248bcf 100644
--- a/extras/hs-test/resources/nginx/vcl.conf
+++ b/extras/hs-test/resources/nginx/vcl.conf
@@ -5,7 +5,6 @@ vcl {
rx-fifo-size 4000000
tx-fifo-size 4000000
event-queue-size 100000
-
use-mq-eventfd
app-socket-api /tmp/nginx/var/run/app_ns_sockets/default
}
diff --git a/extras/hs-test/script/build_boringssl.sh b/extras/hs-test/script/build_boringssl.sh
deleted file mode 100755
index cca4e4a31d1..00000000000
--- a/extras/hs-test/script/build_boringssl.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-cd boringssl || exit 1
-cmake -GNinja -B build
-ninja -C build
diff --git a/extras/hs-test/script/build_hst.sh b/extras/hs-test/script/build_hst.sh
index 9b11f5f0272..a072abdb29d 100755
--- a/extras/hs-test/script/build_hst.sh
+++ b/extras/hs-test/script/build_hst.sh
@@ -85,9 +85,8 @@ docker_build hs-test/vpp vpp
docker_build hs-test/nginx-ldp nginx
docker_build hs-test/nginx-server nginx-server
docker_build hs-test/curl curl
-if [ "$HST_EXTENDED_TESTS" = true ] ; then
- docker_build hs-test/nginx-http3 nginx-http3
-fi
+docker_build hs-test/envoy envoy
+docker_build hs-test/nginx-http3 nginx-http3
# cleanup detached images
images=$(docker images --filter "dangling=true" -q --no-trunc)
diff --git a/extras/hs-test/script/build_nginx.sh b/extras/hs-test/script/build_nginx.sh
deleted file mode 100755
index f21201c4297..00000000000
--- a/extras/hs-test/script/build_nginx.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-cd nginx || exit 1
-./auto/configure --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto" --without-http_rewrite_module --without-http_gzip_module
-make
-make install
diff --git a/extras/hs-test/script/compress.sh b/extras/hs-test/script/compress.sh
index 09db9b6720d..ebc60d25779 100755
--- a/extras/hs-test/script/compress.sh
+++ b/extras/hs-test/script/compress.sh
@@ -1,12 +1,17 @@
#!/usr/bin/env bash
+if [ $1 == 2 ]
+then
+ exit 1
+fi
+
# if failed-summary.log is not empty, exit status = 1
if [ -s "${HS_ROOT}/summary/failed-summary.log" ]
then
if [ -n "${WORKSPACE}" ]
then
echo -n "Copying docker logs..."
- dirs=$(jq -r '.[0] | .SpecReports[] | select(.State == "failed") | .LeafNodeText | split("/")[1]' ${HS_ROOT}/summary/report.json)
+ dirs=$(jq -r '.[0] | .SpecReports[] | select((.State == "failed") or (.State == "timedout") or (.State == "panicked")) | .LeafNodeText | split("/")[1]' ${HS_ROOT}/summary/report.json)
for dirName in $dirs; do
logDir=/tmp/hs-test/$dirName
if [ -d "$logDir" ]; then
diff --git a/extras/hs-test/topo-containers/envoyProxy.yaml b/extras/hs-test/topo-containers/envoyProxy.yaml
index 92dd9b93c47..cbb00d868db 100644
--- a/extras/hs-test/topo-containers/envoyProxy.yaml
+++ b/extras/hs-test/topo-containers/envoyProxy.yaml
@@ -20,9 +20,8 @@ containers:
- name: "ENVOY_UID"
value: "0"
- name: "VCL_CONFIG"
- value: "/tmp/vcl.conf"
- image: "envoyproxy/envoy-contrib:v1.30-latest"
- extra-args: "--log-format [%t][%l][%g:%#]%_ --concurrency 2 -c /etc/envoy/envoy.yaml"
+ value: /tmp/vcl.conf
+ image: "hs-test/envoy"
is-optional: true
- name: "nginx-server"
volumes:
diff --git a/extras/hs-test/topo-containers/ns.yaml b/extras/hs-test/topo-containers/ns.yaml
deleted file mode 100644
index 3de5af59569..00000000000
--- a/extras/hs-test/topo-containers/ns.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
----
-volumes:
- - volume: &shared-vol
- host-dir: "$HST_VOLUME_DIR/shared-vol"
-
-# $HST_DIR will be replaced during runtime by path to hs-test directory
-containers:
- - name: "vpp"
- volumes:
- - <<: *shared-vol
- container-dir: "/tmp/vpp"
- is-default-work-dir: true
- - name: "envoy"
- volumes:
- - <<: *shared-vol
- container-dir: "/tmp/vpp-envoy"
- is-default-work-dir: true
- - host-dir: "$HST_DIR/resources/envoy"
- container-dir: "/tmp"
- vars:
- - name: "ENVOY_UID"
- value: "0"
- - name: "VCL_CONFIG"
- value: "/tmp/vcl.conf"
- image: "envoyproxy/envoy-contrib:v1.30-latest"
- extra-args: "--concurrency 2 -c /etc/envoy/envoy.yaml"
- is-optional: true
diff --git a/extras/hs-test/vcl_test.go b/extras/hs-test/vcl_test.go
index 81da0c533b9..68ca9d02097 100644
--- a/extras/hs-test/vcl_test.go
+++ b/extras/hs-test/vcl_test.go
@@ -51,7 +51,7 @@ func testXEchoVclClient(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -N 100 -p " + proto + " " + serverVeth.Ip4AddressString() + " " + port
s.Log(testClientCommand)
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(testClientCommand)
+ o := echoClnContainer.Exec(true, testClientCommand)
s.Log(o)
s.AssertContains(o, "CLIENT RESULTS")
}
@@ -72,7 +72,7 @@ func testXEchoVclServer(s *VethsSuite, proto string) {
srvAppCont.CreateFile("/vcl.conf", getVclConfig(srvVppCont))
srvAppCont.AddEnvVar("VCL_CONFIG", "/vcl.conf")
vclSrvCmd := fmt.Sprintf("vcl_test_server -p %s %s", proto, port)
- srvAppCont.ExecServer(vclSrvCmd)
+ srvAppCont.ExecServer(true, vclSrvCmd)
serverVeth := s.GetInterfaceByName(ServerInterfaceName)
serverVethAddress := serverVeth.Ip4AddressString()
@@ -90,7 +90,7 @@ func testVclEcho(s *VethsSuite, proto string) {
srvAppCont.CreateFile("/vcl.conf", getVclConfig(srvVppCont))
srvAppCont.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- srvAppCont.ExecServer("vcl_test_server -p " + proto + " " + port)
+ srvAppCont.ExecServer(true, "vcl_test_server -p "+proto+" "+port)
serverVeth := s.GetInterfaceByName(ServerInterfaceName)
serverVethAddress := serverVeth.Ip4AddressString()
@@ -100,7 +100,7 @@ func testVclEcho(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -p " + proto + " " + serverVethAddress + " " + port
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(testClientCommand)
+ o := echoClnContainer.Exec(true, testClientCommand)
s.Log(o)
}
@@ -128,7 +128,7 @@ func testRetryAttach(s *VethsSuite, proto string) {
echoSrvContainer.CreateFile("/vcl.conf", getVclConfig(echoSrvContainer))
echoSrvContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- echoSrvContainer.ExecServer("vcl_test_server -p " + proto + " 12346")
+ echoSrvContainer.ExecServer(true, "vcl_test_server -p "+proto+" 12346")
s.Log("This whole test case can take around 3 minutes to run. Please be patient.")
s.Log("... Running first echo client test, before disconnect.")
@@ -141,14 +141,14 @@ func testRetryAttach(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -U -p " + proto + " " + serverVethAddress + " 12346"
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(testClientCommand)
+ o := echoClnContainer.Exec(true, testClientCommand)
s.Log(o)
s.Log("... First test ended. Stopping VPP server now.")
// Stop server-vpp-instance, start it again and then run vcl-test-client once more
srvVppContainer.VppInstance.Disconnect()
stopVppCommand := "/bin/bash -c 'ps -C vpp_main -o pid= | xargs kill -9'"
- srvVppContainer.Exec(stopVppCommand)
+ srvVppContainer.Exec(false, stopVppCommand)
s.SetupServerVpp()
@@ -156,7 +156,7 @@ func testRetryAttach(s *VethsSuite, proto string) {
time.Sleep(30 * time.Second) // Wait a moment for the re-attachment to happen
s.Log("... Running second echo client test, after disconnect and re-attachment.")
- o = echoClnContainer.Exec(testClientCommand)
+ o = echoClnContainer.Exec(true, testClientCommand)
s.Log(o)
s.Log("Done.")
}
diff --git a/extras/scripts/crcchecker.py b/extras/scripts/crcchecker.py
index 7dcdb681e18..4a8f9b16669 100755
--- a/extras/scripts/crcchecker.py
+++ b/extras/scripts/crcchecker.py
@@ -40,10 +40,13 @@ def crc_from_apigen(revision, filename):
if returncode.returncode != 0:
print(
f"vppapigen failed for {revision}:{filename} with "
- "command\n {apigen}\n error: {rv}",
- returncode.stderr.decode("ascii"),
+ f"command:\n {apigen}\n error: {returncode.returncode}",
file=sys.stderr,
)
+ if returncode.stderr:
+ print(f"stderr: {returncode.stderr.decode('ascii')}", file=sys.stderr)
+ if returncode.stdout:
+ print(f"stdout: {returncode.stdout.decode('ascii')}", file=sys.stderr)
sys.exit(-2)
return json.loads(returncode.stdout)
diff --git a/extras/vpp_if_stats/apimock.go b/extras/vpp_if_stats/apimock.go
index 77363344090..25e76ed1d31 100755
--- a/extras/vpp_if_stats/apimock.go
+++ b/extras/vpp_if_stats/apimock.go
@@ -5,10 +5,11 @@
package main
import (
- api "git.fd.io/govpp.git/api"
- gomock "github.com/golang/mock/gomock"
reflect "reflect"
time "time"
+
+ api "git.fd.io/govpp.git/api"
+ gomock "github.com/golang/mock/gomock"
)
// MockChannel is a mock of Channel interface
diff --git a/extras/vpp_if_stats/json_structs.go b/extras/vpp_if_stats/json_structs.go
index a42b6d815b2..8e73337418e 100755
--- a/extras/vpp_if_stats/json_structs.go
+++ b/extras/vpp_if_stats/json_structs.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
+
"git.fd.io/govpp.git/examples/bin_api/vpe"
)
diff --git a/extras/vpp_if_stats/statsmock.go b/extras/vpp_if_stats/statsmock.go
index 72528f53d9a..172176fa744 100755
--- a/extras/vpp_if_stats/statsmock.go
+++ b/extras/vpp_if_stats/statsmock.go
@@ -5,9 +5,10 @@
package main
import (
+ reflect "reflect"
+
adapter "git.fd.io/govpp.git/adapter"
gomock "github.com/golang/mock/gomock"
- reflect "reflect"
)
// MockStatsAPI is a mock of StatsAPI interface
diff --git a/extras/vpp_if_stats/vpp_if_stats.go b/extras/vpp_if_stats/vpp_if_stats.go
index 90c1700430c..751bbe5d5a9 100644
--- a/extras/vpp_if_stats/vpp_if_stats.go
+++ b/extras/vpp_if_stats/vpp_if_stats.go
@@ -3,6 +3,8 @@ package main
import (
"flag"
"fmt"
+ "log"
+
"git.fd.io/govpp.git"
"git.fd.io/govpp.git/adapter"
"git.fd.io/govpp.git/adapter/vppapiclient"
@@ -10,7 +12,6 @@ import (
"git.fd.io/govpp.git/core"
"git.fd.io/govpp.git/examples/bin_api/interfaces"
"git.fd.io/govpp.git/examples/bin_api/vpe"
- "log"
)
//////////////////////////////////////
diff --git a/extras/vpp_if_stats/vpp_if_stats_test.go b/extras/vpp_if_stats/vpp_if_stats_test.go
index 3c22ce85d75..53c990c4158 100644
--- a/extras/vpp_if_stats/vpp_if_stats_test.go
+++ b/extras/vpp_if_stats/vpp_if_stats_test.go
@@ -1,15 +1,16 @@
package main
import (
+ "math/rand"
+ "testing"
+ "time"
+
"git.fd.io/govpp.git/adapter"
"git.fd.io/govpp.git/api"
"git.fd.io/govpp.git/examples/bin_api/interfaces"
"git.fd.io/govpp.git/examples/bin_api/vpe"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
- "math/rand"
- "testing"
- "time"
)
var (