benchmark_test.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package benchmark
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "fmt"
  6. "io"
  7. "math/rand"
  8. "net"
  9. quic "github.com/lucas-clemente/quic-go"
  10. _ "github.com/lucas-clemente/quic-go/integrationtests/tools/testlog"
  11. "github.com/lucas-clemente/quic-go/internal/protocol"
  12. "github.com/lucas-clemente/quic-go/internal/testdata"
  13. . "github.com/onsi/ginkgo"
  14. . "github.com/onsi/gomega"
  15. )
  16. func init() {
  17. var _ = Describe("Benchmarks", func() {
  18. dataLen := size * /* MB */ 1e6
  19. data := make([]byte, dataLen)
  20. rand.Seed(GinkgoRandomSeed())
  21. rand.Read(data) // no need to check for an error. math.Rand.Read never errors
  22. for i := range protocol.SupportedVersions {
  23. version := protocol.SupportedVersions[i]
  24. Context(fmt.Sprintf("with version %s", version), func() {
  25. Measure(fmt.Sprintf("transferring a %d MB file", size), func(b Benchmarker) {
  26. var ln quic.Listener
  27. serverAddr := make(chan net.Addr)
  28. handshakeChan := make(chan struct{})
  29. // start the server
  30. go func() {
  31. defer GinkgoRecover()
  32. var err error
  33. ln, err = quic.ListenAddr(
  34. "localhost:0",
  35. testdata.GetTLSConfig(),
  36. &quic.Config{Versions: []protocol.VersionNumber{version}},
  37. )
  38. Expect(err).ToNot(HaveOccurred())
  39. serverAddr <- ln.Addr()
  40. sess, err := ln.Accept()
  41. Expect(err).ToNot(HaveOccurred())
  42. // wait for the client to complete the handshake before sending the data
  43. // this should not be necessary, but due to timing issues on the CIs, this is necessary to avoid sending too many undecryptable packets
  44. <-handshakeChan
  45. str, err := sess.OpenStream()
  46. Expect(err).ToNot(HaveOccurred())
  47. _, err = str.Write(data)
  48. Expect(err).ToNot(HaveOccurred())
  49. err = str.Close()
  50. Expect(err).ToNot(HaveOccurred())
  51. }()
  52. // start the client
  53. addr := <-serverAddr
  54. sess, err := quic.DialAddr(
  55. addr.String(),
  56. &tls.Config{InsecureSkipVerify: true},
  57. &quic.Config{Versions: []protocol.VersionNumber{version}},
  58. )
  59. Expect(err).ToNot(HaveOccurred())
  60. close(handshakeChan)
  61. str, err := sess.AcceptStream()
  62. Expect(err).ToNot(HaveOccurred())
  63. buf := &bytes.Buffer{}
  64. // measure the time it takes to download the dataLen bytes
  65. // note we're measuring the time for the transfer, i.e. excluding the handshake
  66. runtime := b.Time("transfer time", func() {
  67. _, err := io.Copy(buf, str)
  68. Expect(err).NotTo(HaveOccurred())
  69. })
  70. Expect(buf.Bytes()).To(Equal(data))
  71. b.RecordValue("transfer rate [MB/s]", float64(dataLen)/1e6/runtime.Seconds())
  72. ln.Close()
  73. sess.Close()
  74. }, samples)
  75. })
  76. }
  77. })
  78. }