http: fix http server in response
[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, HeaderServerTest)
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 HeaderServerTest(s *NoTopoSuite) {
95         query := "show/version"
96         vpp := s.getContainerByName("vpp").vppInstance
97         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
98         vpp.vppctl("http cli server")
99
100         curlCont := s.getContainerByName("curl")
101         args := fmt.Sprintf("curl -i -s http://%s:80/%s", serverAddress, query)
102         curlCont.extraRunningArgs = args
103         o, err := curlCont.combinedOutput()
104         s.assertNil(err, fmt.Sprint(err))
105         s.log(o)
106         s.assertContains(o, "Server: http_cli_server")
107 }
108
109 func NginxAsServerTest(s *NoTopoSuite) {
110         query := "return_ok"
111         finished := make(chan error, 1)
112
113         nginxCont := s.getContainerByName("nginx")
114         s.assertNil(nginxCont.run())
115
116         vpp := s.getContainerByName("vpp").vppInstance
117         vpp.waitForApp("nginx-", 5)
118
119         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
120
121         defer func() { os.Remove(query) }()
122         go func() {
123                 defer GinkgoRecover()
124                 s.startWget(finished, serverAddress, "80", query, "")
125         }()
126         s.assertNil(<-finished)
127 }
128
129 func parseString(s, pattern string) string {
130         temp := strings.Split(s, "\n")
131         for _, item := range temp {
132                 if strings.Contains(item, pattern) {
133                         return item
134                 }
135         }
136         return ""
137 }
138
139 func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error {
140         nRequests := 1000000
141         nClients := 1000
142
143         serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
144
145         vpp := s.getContainerByName("vpp").vppInstance
146
147         nginxCont := s.getContainerByName(singleTopoContainerNginx)
148         s.assertNil(nginxCont.run())
149         vpp.waitForApp("nginx-", 5)
150
151         if ab_or_wrk == "ab" {
152                 abCont := s.getContainerByName("ab")
153                 args := fmt.Sprintf("-n %d -c %d", nRequests, nClients)
154                 if mode == "rps" {
155                         args += " -k"
156                 } else if mode != "cps" {
157                         return fmt.Errorf("invalid mode %s; expected cps/rps", mode)
158                 }
159                 // don't exit on socket receive errors
160                 args += " -r"
161                 args += " http://" + serverAddress + ":80/64B.json"
162                 abCont.extraRunningArgs = args
163                 time.Sleep(time.Second * 10)
164                 o, err := abCont.combinedOutput()
165                 rps := parseString(o, "Requests per second:")
166                 s.log(rps)
167                 s.log(err)
168                 s.assertNil(err, "err: '%s', output: '%s'", err, o)
169         } else {
170                 wrkCont := s.getContainerByName("wrk")
171                 args := fmt.Sprintf("-c %d -t 2 -d 30 http://%s:80/64B.json", nClients,
172                         serverAddress)
173                 wrkCont.extraRunningArgs = args
174                 o, err := wrkCont.combinedOutput()
175                 rps := parseString(o, "requests")
176                 s.log(rps)
177                 s.log(err)
178                 s.assertNil(err, "err: '%s', output: '%s'", err, o)
179         }
180         return nil
181 }
182
183 func NginxPerfCpsTest(s *NoTopoSuite) {
184         s.assertNil(runNginxPerf(s, "cps", "ab"))
185 }
186
187 func NginxPerfRpsTest(s *NoTopoSuite) {
188         s.assertNil(runNginxPerf(s, "rps", "ab"))
189 }
190
191 func NginxPerfWrkTest(s *NoTopoSuite) {
192         s.assertNil(runNginxPerf(s, "", "wrk"))
193 }