acd026d484f6038d824a64ce79994658ae3e6307
[vpp.git] / extras / hs-test / http_test.go
1 package main
2
3 import (
4         "fmt"
5         "os"
6         "strings"
7         "time"
8
9         . "github.com/onsi/ginkgo/v2"
10 )
11
12 func init() {
13         registerNsTests(HttpTpsTest)
14         registerVethTests(HttpCliTest)
15         registerNoTopoTests(NginxHttp3Test, NginxAsServerTest,
16                 NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest)
17         registerNoTopoSoloTests(HttpStaticPromTest)
18 }
19
20 func HttpTpsTest(s *NsSuite) {
21         iface := s.getInterfaceByName(clientInterface)
22         client_ip := iface.ip4AddressString()
23         port := "8080"
24         finished := make(chan error, 1)
25         clientNetns := s.getNetNamespaceByName("cln")
26
27         container := s.getContainerByName("vpp")
28
29         // configure vpp in the container
30         container.vppInstance.vppctl("http tps uri tcp://0.0.0.0/8080")
31
32         go func() {
33                 defer GinkgoRecover()
34                 s.startWget(finished, client_ip, port, "test_file_10M", clientNetns)
35         }()
36         // wait for client
37         err := <-finished
38         s.assertNil(err, fmt.Sprint(err))
39 }
40
41 func HttpCliTest(s *VethsSuite) {
42         serverContainer := s.getContainerByName("server-vpp")
43         clientContainer := s.getContainerByName("client-vpp")
44
45         serverVeth := s.getInterfaceByName(serverInterfaceName)
46
47         serverContainer.vppInstance.vppctl("http cli server")
48
49         uri := "http://" + serverVeth.ip4AddressString() + "/80"
50
51         o := clientContainer.vppInstance.vppctl("http cli client" +
52                 " uri " + uri + " query /show/vlib/graph")
53
54         s.log(o)
55         s.assertContains(o, "<html>", "<html> not found in the result!")
56 }
57
58 func NginxHttp3Test(s *NoTopoSuite) {
59         s.SkipUnlessExtendedTestsBuilt()
60
61         query := "index.html"
62         nginxCont := s.getContainerByName("nginx-http3")
63         s.assertNil(nginxCont.run())
64
65         vpp := s.getContainerByName("vpp").vppInstance
66         vpp.waitForApp("nginx-", 5)
67         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
68
69         defer func() { os.Remove(query) }()
70         curlCont := s.getContainerByName("curl")
71         args := fmt.Sprintf("curl --noproxy '*' --local-port 55444 --http3-only -k https://%s:8443/%s", serverAddress, query)
72         curlCont.extraRunningArgs = args
73         o, err := curlCont.combinedOutput()
74         s.assertNil(err, fmt.Sprint(err))
75         s.assertContains(o, "<http>", "<http> not found in the result!")
76 }
77
78 func HttpStaticPromTest(s *NoTopoSuite) {
79         finished := make(chan error, 1)
80         query := "stats.prom"
81         vpp := s.getContainerByName("vpp").vppInstance
82         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
83         s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
84         s.log(vpp.vppctl("prom enable"))
85         time.Sleep(time.Second * 5)
86         go func() {
87                 defer GinkgoRecover()
88                 s.startWget(finished, serverAddress, "80", query, "")
89         }()
90         err := <-finished
91         s.assertNil(err)
92 }
93
94 func NginxAsServerTest(s *NoTopoSuite) {
95         query := "return_ok"
96         finished := make(chan error, 1)
97
98         nginxCont := s.getContainerByName("nginx")
99         s.assertNil(nginxCont.run())
100
101         vpp := s.getContainerByName("vpp").vppInstance
102         vpp.waitForApp("nginx-", 5)
103
104         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
105
106         defer func() { os.Remove(query) }()
107         go func() {
108                 defer GinkgoRecover()
109                 s.startWget(finished, serverAddress, "80", query, "")
110         }()
111         s.assertNil(<-finished)
112 }
113
114 func parseString(s, pattern string) string {
115         temp := strings.Split(s, "\n")
116         for _, item := range temp {
117                 if strings.Contains(item, pattern) {
118                         return item
119                 }
120         }
121         return ""
122 }
123
124 func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
125         nRequests := 1000000
126         nClients := 1000
127
128         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
129
130         vpp := s.getContainerByName("vpp").vppInstance
131
132         nginxCont := s.getContainerByName(singleTopoContainerNginx)
133         s.assertNil(nginxCont.run())
134         vpp.waitForApp("nginx-", 5)
135
136         if ab_or_wrk == "ab" {
137                 abCont := s.getContainerByName("ab")
138                 args := fmt.Sprintf("-n %d -c %d", nRequests, nClients)
139                 if mode == "rps" {
140                         args += " -k"
141                 } else if mode != "cps" {
142                         return fmt.Errorf("invalid mode %s; expected cps/rps", mode)
143                 }
144                 // don't exit on socket receive errors
145                 args += " -r"
146                 args += " http://" + serverAddress + ":80/64B.json"
147                 abCont.extraRunningArgs = args
148                 time.Sleep(time.Second * 10)
149                 o, err := abCont.combinedOutput()
150                 rps := parseString(o, "Requests per second:")
151                 s.log(rps)
152                 s.log(err)
153                 s.assertNil(err, "err: '%s', output: '%s'", err, o)
154         } else {
155                 wrkCont := s.getContainerByName("wrk")
156                 args := fmt.Sprintf("-c %d -t 2 -d 30 http://%s:80/64B.json", nClients,
157                         serverAddress)
158                 wrkCont.extraRunningArgs = args
159                 o, err := wrkCont.combinedOutput()
160                 rps := parseString(o, "requests")
161                 s.log(rps)
162                 s.log(err)
163                 s.assertNil(err, "err: '%s', output: '%s'", err, o)
164         }
165         return nil
166 }
167
168 func NginxPerfCpsTest(s *NoTopoSuite) {
169         s.assertNil(runNginxPerf(s, "cps", "ab"))
170 }
171
172 func NginxPerfRpsTest(s *NoTopoSuite) {
173         s.assertNil(runNginxPerf(s, "rps", "ab"))
174 }
175
176 func NginxPerfWrkTest(s *NoTopoSuite) {
177         s.assertNil(runNginxPerf(s, "", "wrk"))
178 }