blob: f7a160c876423f4bfda63690c0c8704fff2a4a03 [file] [log] [blame]
Filip Tehlarb15a0002022-11-10 12:34:17 +01001package main
2
Filip Tehlarc204c872022-12-21 08:59:16 +01003import (
Filip Tehlar8df3de42023-01-27 13:14:34 +01004 "fmt"
Matus Fabianb7a9ed72024-05-10 16:20:40 +02005 "net/http"
Filip Tehlarc204c872022-12-21 08:59:16 +01006 "os"
Filip Tehlar58113562023-04-15 20:41:18 +02007 "strings"
Adrian Villincee15aa2024-03-14 11:42:55 -04008 "time"
9
10 . "github.com/onsi/ginkgo/v2"
Filip Tehlarc204c872022-12-21 08:59:16 +010011)
12
Adrian Villincee15aa2024-03-14 11:42:55 -040013func init() {
14 registerNsTests(HttpTpsTest)
Matus Fabian3d008932024-05-13 10:29:11 +020015 registerVethTests(HttpCliTest, HttpCliConnectErrorTest)
Adrian Villincee15aa2024-03-14 11:42:55 -040016 registerNoTopoTests(NginxHttp3Test, NginxAsServerTest,
Matus Fabianb7a9ed72024-05-10 16:20:40 +020017 NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest, HeaderServerTest,
18 HttpStaticMovedTest, HttpStaticNotFoundTest, HttpCliMethodNotAllowedTest,
Matus Fabian5409d332024-05-28 13:39:13 +020019 HttpCliBadRequestTest, HttpStaticPathTraversalTest)
Adrian Villincee15aa2024-03-14 11:42:55 -040020 registerNoTopoSoloTests(HttpStaticPromTest)
21}
22
Matus Fabian5409d332024-05-28 13:39:13 +020023const wwwRootPath = "/tmp/www_root"
24
Adrian Villincee15aa2024-03-14 11:42:55 -040025func HttpTpsTest(s *NsSuite) {
adrianvillin28bd8f02024-02-13 06:00:02 -050026 iface := s.getInterfaceByName(clientInterface)
Maros Ondrejickae7625d02023-02-28 16:55:01 +010027 client_ip := iface.ip4AddressString()
Filip Tehlarb15a0002022-11-10 12:34:17 +010028 port := "8080"
Maros Ondrejicka2908f8c2023-02-02 08:58:04 +010029 finished := make(chan error, 1)
adrianvillin28bd8f02024-02-13 06:00:02 -050030 clientNetns := s.getNetNamespaceByName("cln")
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010031
32 container := s.getContainerByName("vpp")
Filip Tehlarb15a0002022-11-10 12:34:17 +010033
Maros Ondrejicka2908f8c2023-02-02 08:58:04 +010034 // configure vpp in the container
35 container.vppInstance.vppctl("http tps uri tcp://0.0.0.0/8080")
Filip Tehlarb15a0002022-11-10 12:34:17 +010036
Adrian Villincee15aa2024-03-14 11:42:55 -040037 go func() {
38 defer GinkgoRecover()
39 s.startWget(finished, client_ip, port, "test_file_10M", clientNetns)
40 }()
Filip Tehlarb15a0002022-11-10 12:34:17 +010041 // wait for client
Maros Ondrejicka2908f8c2023-02-02 08:58:04 +010042 err := <-finished
Adrian Villincee15aa2024-03-14 11:42:55 -040043 s.assertNil(err, fmt.Sprint(err))
Filip Tehlarb15a0002022-11-10 12:34:17 +010044}
45
Adrian Villincee15aa2024-03-14 11:42:55 -040046func HttpCliTest(s *VethsSuite) {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010047 serverContainer := s.getContainerByName("server-vpp")
48 clientContainer := s.getContainerByName("client-vpp")
Filip Tehlarb15a0002022-11-10 12:34:17 +010049
adrianvillin28bd8f02024-02-13 06:00:02 -050050 serverVeth := s.getInterfaceByName(serverInterfaceName)
Maros Ondrejickaffa3f602023-01-26 10:07:29 +010051
Maros Ondrejicka2908f8c2023-02-02 08:58:04 +010052 serverContainer.vppInstance.vppctl("http cli server")
Filip Tehlarb15a0002022-11-10 12:34:17 +010053
Maros Ondrejickae7625d02023-02-28 16:55:01 +010054 uri := "http://" + serverVeth.ip4AddressString() + "/80"
Maros Ondrejickaffa3f602023-01-26 10:07:29 +010055
Maros Ondrejicka2908f8c2023-02-02 08:58:04 +010056 o := clientContainer.vppInstance.vppctl("http cli client" +
Filip Tehlard8944382023-11-27 13:28:36 +010057 " uri " + uri + " query /show/vlib/graph")
Filip Tehlarb15a0002022-11-10 12:34:17 +010058
Maros Ondrejickaffa3f602023-01-26 10:07:29 +010059 s.log(o)
Maros Ondrejicka98a91e82022-12-06 15:38:05 +010060 s.assertContains(o, "<html>", "<html> not found in the result!")
Filip Tehlarb15a0002022-11-10 12:34:17 +010061}
Filip Tehlarc204c872022-12-21 08:59:16 +010062
Matus Fabian3d008932024-05-13 10:29:11 +020063func HttpCliConnectErrorTest(s *VethsSuite) {
64 clientContainer := s.getContainerByName("client-vpp")
65
66 serverVeth := s.getInterfaceByName(serverInterfaceName)
67
68 uri := "http://" + serverVeth.ip4AddressString() + "/80"
69
70 o := clientContainer.vppInstance.vppctl("http cli client" +
71 " uri " + uri + " query /show/vlib/graph")
72
73 s.log(o)
74 s.assertContains(o, "failed to connect")
75}
76
Adrian Villincee15aa2024-03-14 11:42:55 -040077func NginxHttp3Test(s *NoTopoSuite) {
Filip Tehlar31eaea92023-06-15 10:06:57 +020078 s.SkipUnlessExtendedTestsBuilt()
79
80 query := "index.html"
81 nginxCont := s.getContainerByName("nginx-http3")
82 s.assertNil(nginxCont.run())
83
84 vpp := s.getContainerByName("vpp").vppInstance
85 vpp.waitForApp("nginx-", 5)
adrianvillin28bd8f02024-02-13 06:00:02 -050086 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Filip Tehlar31eaea92023-06-15 10:06:57 +020087
88 defer func() { os.Remove(query) }()
89 curlCont := s.getContainerByName("curl")
Filip Tehlar87241fe2024-01-17 21:45:28 +010090 args := fmt.Sprintf("curl --noproxy '*' --local-port 55444 --http3-only -k https://%s:8443/%s", serverAddress, query)
Filip Tehlar31eaea92023-06-15 10:06:57 +020091 curlCont.extraRunningArgs = args
92 o, err := curlCont.combinedOutput()
Florin Coras07994a22024-06-06 03:08:27 -040093 s.log(o)
Adrian Villincee15aa2024-03-14 11:42:55 -040094 s.assertNil(err, fmt.Sprint(err))
Filip Tehlar31eaea92023-06-15 10:06:57 +020095 s.assertContains(o, "<http>", "<http> not found in the result!")
96}
97
Adrian Villincee15aa2024-03-14 11:42:55 -040098func HttpStaticPromTest(s *NoTopoSuite) {
Filip Tehlarcc1475c2023-11-29 12:59:05 +010099 finished := make(chan error, 1)
100 query := "stats.prom"
101 vpp := s.getContainerByName("vpp").vppInstance
adrianvillin28bd8f02024-02-13 06:00:02 -0500102 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100103 s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
104 s.log(vpp.vppctl("prom enable"))
Adrian Villincee15aa2024-03-14 11:42:55 -0400105 time.Sleep(time.Second * 5)
106 go func() {
107 defer GinkgoRecover()
108 s.startWget(finished, serverAddress, "80", query, "")
109 }()
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100110 err := <-finished
Adrian Villincee15aa2024-03-14 11:42:55 -0400111 s.assertNil(err)
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100112}
113
Matus Fabian5409d332024-05-28 13:39:13 +0200114func HttpStaticPathTraversalTest(s *NoTopoSuite) {
115 vpp := s.getContainerByName("vpp").vppInstance
116 vpp.container.exec("mkdir -p " + wwwRootPath)
117 vpp.container.exec("mkdir -p " + "/tmp/secret_folder")
118 vpp.container.createFile("/tmp/secret_folder/secret_file.txt", "secret")
119 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
120 s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
121
122 client := newHttpClient()
123 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/../secret_folder/secret_file.txt", nil)
124 s.assertNil(err, fmt.Sprint(err))
125 resp, err := client.Do(req)
126 s.assertNil(err, fmt.Sprint(err))
127 defer resp.Body.Close()
128 s.assertEqual(404, resp.StatusCode)
129}
130
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200131func HttpStaticMovedTest(s *NoTopoSuite) {
132 vpp := s.getContainerByName("vpp").vppInstance
Matus Fabian5409d332024-05-28 13:39:13 +0200133 vpp.container.exec("mkdir -p " + wwwRootPath + "/tmp.aaa")
134 vpp.container.createFile(wwwRootPath+"/tmp.aaa/index.html", "<http><body><p>Hello</p></body></http>")
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200135 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Matus Fabian5409d332024-05-28 13:39:13 +0200136 s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200137
Matus Fabian5409d332024-05-28 13:39:13 +0200138 client := newHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200139 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/tmp.aaa", nil)
140 s.assertNil(err, fmt.Sprint(err))
141 resp, err := client.Do(req)
142 s.assertNil(err, fmt.Sprint(err))
143 defer resp.Body.Close()
144 s.assertEqual(301, resp.StatusCode)
145 s.assertNotEqual("", resp.Header.Get("Location"))
146}
147
148func HttpStaticNotFoundTest(s *NoTopoSuite) {
149 vpp := s.getContainerByName("vpp").vppInstance
Matus Fabian5409d332024-05-28 13:39:13 +0200150 vpp.container.exec("mkdir -p " + wwwRootPath)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200151 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Matus Fabian5409d332024-05-28 13:39:13 +0200152 s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200153
Matus Fabian5409d332024-05-28 13:39:13 +0200154 client := newHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200155 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/notfound.html", nil)
156 s.assertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200157 resp, err := client.Do(req)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200158 s.assertNil(err, fmt.Sprint(err))
159 defer resp.Body.Close()
160 s.assertEqual(404, resp.StatusCode)
161}
162
163func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
Matus Fabian616201a2024-05-02 11:17:15 +0200164 vpp := s.getContainerByName("vpp").vppInstance
165 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
166 vpp.vppctl("http cli server")
167
Matus Fabian5409d332024-05-28 13:39:13 +0200168 client := newHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200169 req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test", nil)
Matus Fabian616201a2024-05-02 11:17:15 +0200170 s.assertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200171 resp, err := client.Do(req)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200172 s.assertNil(err, fmt.Sprint(err))
173 defer resp.Body.Close()
174 s.assertEqual(405, resp.StatusCode)
175 // TODO: need to be fixed in http code
176 //s.assertNotEqual("", resp.Header.Get("Allow"))
177}
178
179func HttpCliBadRequestTest(s *NoTopoSuite) {
180 vpp := s.getContainerByName("vpp").vppInstance
181 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
182 vpp.vppctl("http cli server")
183
Matus Fabian5409d332024-05-28 13:39:13 +0200184 client := newHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200185 req, err := http.NewRequest("GET", "http://"+serverAddress+":80", nil)
186 s.assertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200187 resp, err := client.Do(req)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200188 s.assertNil(err, fmt.Sprint(err))
189 defer resp.Body.Close()
190 s.assertEqual(400, resp.StatusCode)
191}
192
193func HeaderServerTest(s *NoTopoSuite) {
194 vpp := s.getContainerByName("vpp").vppInstance
195 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
196 vpp.vppctl("http cli server")
197
Matus Fabian5409d332024-05-28 13:39:13 +0200198 client := newHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200199 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/show/version", nil)
200 s.assertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200201 resp, err := client.Do(req)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200202 s.assertNil(err, fmt.Sprint(err))
203 defer resp.Body.Close()
204 s.assertEqual("http_cli_server", resp.Header.Get("Server"))
Matus Fabian616201a2024-05-02 11:17:15 +0200205}
206
Adrian Villincee15aa2024-03-14 11:42:55 -0400207func NginxAsServerTest(s *NoTopoSuite) {
Filip Tehlarc204c872022-12-21 08:59:16 +0100208 query := "return_ok"
209 finished := make(chan error, 1)
Filip Tehlarc204c872022-12-21 08:59:16 +0100210
211 nginxCont := s.getContainerByName("nginx")
212 s.assertNil(nginxCont.run())
213
Maros Ondrejicka7550dd22023-02-07 20:40:27 +0100214 vpp := s.getContainerByName("vpp").vppInstance
Florin Corase2415f72023-02-28 14:51:03 -0800215 vpp.waitForApp("nginx-", 5)
Filip Tehlarc204c872022-12-21 08:59:16 +0100216
adrianvillin28bd8f02024-02-13 06:00:02 -0500217 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Maros Ondrejicka7550dd22023-02-07 20:40:27 +0100218
Filip Tehlarc204c872022-12-21 08:59:16 +0100219 defer func() { os.Remove(query) }()
Adrian Villincee15aa2024-03-14 11:42:55 -0400220 go func() {
221 defer GinkgoRecover()
222 s.startWget(finished, serverAddress, "80", query, "")
223 }()
Filip Tehlarc204c872022-12-21 08:59:16 +0100224 s.assertNil(<-finished)
225}
Filip Tehlar8df3de42023-01-27 13:14:34 +0100226
Filip Tehlar58113562023-04-15 20:41:18 +0200227func parseString(s, pattern string) string {
228 temp := strings.Split(s, "\n")
229 for _, item := range temp {
230 if strings.Contains(item, pattern) {
231 return item
232 }
233 }
234 return ""
235}
236
Filip Tehlar8df3de42023-01-27 13:14:34 +0100237func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
238 nRequests := 1000000
Filip Tehlardda1f682023-04-24 17:52:50 +0200239 nClients := 1000
Filip Tehlar8df3de42023-01-27 13:14:34 +0100240
adrianvillin28bd8f02024-02-13 06:00:02 -0500241 serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
Maros Ondrejicka7550dd22023-02-07 20:40:27 +0100242
Maros Ondrejicka7550dd22023-02-07 20:40:27 +0100243 vpp := s.getContainerByName("vpp").vppInstance
Filip Tehlar8df3de42023-01-27 13:14:34 +0100244
adrianvillinfbf5f2b2024-02-13 03:26:25 -0500245 nginxCont := s.getContainerByName(singleTopoContainerNginx)
Filip Tehlar8df3de42023-01-27 13:14:34 +0100246 s.assertNil(nginxCont.run())
Florin Corase2415f72023-02-28 14:51:03 -0800247 vpp.waitForApp("nginx-", 5)
Filip Tehlar8df3de42023-01-27 13:14:34 +0100248
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100249 if ab_or_wrk == "ab" {
250 abCont := s.getContainerByName("ab")
Adrian Villin7ad37b52024-06-05 05:53:50 -0400251 abCont.runDetached = true
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100252 args := fmt.Sprintf("-n %d -c %d", nRequests, nClients)
253 if mode == "rps" {
254 args += " -k"
255 } else if mode != "cps" {
256 return fmt.Errorf("invalid mode %s; expected cps/rps", mode)
257 }
Filip Tehlardda1f682023-04-24 17:52:50 +0200258 // don't exit on socket receive errors
259 args += " -r"
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100260 args += " http://" + serverAddress + ":80/64B.json"
261 abCont.extraRunningArgs = args
262 o, err := abCont.combinedOutput()
Filip Tehlar58113562023-04-15 20:41:18 +0200263 rps := parseString(o, "Requests per second:")
Adrian Villincee15aa2024-03-14 11:42:55 -0400264 s.log(rps)
265 s.log(err)
adrianvillin7c675472024-02-12 02:44:53 -0500266 s.assertNil(err, "err: '%s', output: '%s'", err, o)
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100267 } else {
268 wrkCont := s.getContainerByName("wrk")
Adrian Villin7ad37b52024-06-05 05:53:50 -0400269 wrkCont.runDetached = true
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100270 args := fmt.Sprintf("-c %d -t 2 -d 30 http://%s:80/64B.json", nClients,
271 serverAddress)
272 wrkCont.extraRunningArgs = args
273 o, err := wrkCont.combinedOutput()
Filip Tehlar58113562023-04-15 20:41:18 +0200274 rps := parseString(o, "requests")
Adrian Villincee15aa2024-03-14 11:42:55 -0400275 s.log(rps)
276 s.log(err)
adrianvillin7c675472024-02-12 02:44:53 -0500277 s.assertNil(err, "err: '%s', output: '%s'", err, o)
Filip Tehlarb41b0af2023-03-20 12:39:20 +0100278 }
Filip Tehlar8df3de42023-01-27 13:14:34 +0100279 return nil
280}
281
Adrian Villin0df582e2024-05-22 09:26:47 -0400282// unstable with multiple workers
Adrian Villincee15aa2024-03-14 11:42:55 -0400283func NginxPerfCpsTest(s *NoTopoSuite) {
Adrian Villin0df582e2024-05-22 09:26:47 -0400284 s.SkipIfMultiWorker()
Filip Tehlar8df3de42023-01-27 13:14:34 +0100285 s.assertNil(runNginxPerf(s, "cps", "ab"))
286}
287
Adrian Villincee15aa2024-03-14 11:42:55 -0400288func NginxPerfRpsTest(s *NoTopoSuite) {
Filip Tehlar8df3de42023-01-27 13:14:34 +0100289 s.assertNil(runNginxPerf(s, "rps", "ab"))
290}
291
Adrian Villincee15aa2024-03-14 11:42:55 -0400292func NginxPerfWrkTest(s *NoTopoSuite) {
Filip Tehlar8df3de42023-01-27 13:14:34 +0100293 s.assertNil(runNginxPerf(s, "", "wrk"))
294}