gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/network/nginx_test.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package network
    15  
    16  import (
    17  	"os"
    18  	"strconv"
    19  	"testing"
    20  
    21  	"gvisor.dev/gvisor/pkg/test/dockerutil"
    22  	"gvisor.dev/gvisor/test/benchmarks/harness"
    23  	"gvisor.dev/gvisor/test/benchmarks/tools"
    24  )
    25  
    26  // see Dockerfile '//images/benchmarks/nginx'.
    27  var nginxDocs = map[string]string{
    28  	"notfound": "notfound",
    29  	"1Kb":      "latin1k.txt",
    30  	"10Kb":     "latin10k.txt",
    31  	"100Kb":    "latin100k.txt",
    32  	"1Mb":      "latin1024k.txt",
    33  	"10Mb":     "latin10240k.txt",
    34  }
    35  
    36  // BenchmarkNginxDocSize iterates over different sized payloads, testing how
    37  // well the runtime handles sending different payload sizes.
    38  func BenchmarkNginxDocSize(b *testing.B) {
    39  	benchmarkNginxDocSize(b, true /* tmpfs */)
    40  	benchmarkNginxDocSize(b, false /* tmpfs */)
    41  }
    42  
    43  // BenchmarkContinuousNginx runs specific benchmarks for continous jobs.
    44  // The runtime under test is the sever serving a runc client.
    45  func BenchmarkContinuousNginx(b *testing.B) {
    46  	sizes := []string{"10Kb", "100Kb", "1Mb"}
    47  	threads := []int{1, 25, 100, 1000}
    48  	benchmarkNginxContinuous(b, threads, sizes)
    49  }
    50  
    51  // benchmarkNginxDocSize iterates through all doc sizes, running subbenchmarks
    52  // for each size.
    53  func benchmarkNginxDocSize(b *testing.B, tmpfs bool) {
    54  	for size, filename := range nginxDocs {
    55  		concurrency := []int{1, 25, 50, 100, 1000}
    56  		for _, c := range concurrency {
    57  			fsize := tools.Parameter{
    58  				Name:  "filesize",
    59  				Value: size,
    60  			}
    61  
    62  			threads := tools.Parameter{
    63  				Name:  "concurrency",
    64  				Value: strconv.Itoa(c),
    65  			}
    66  
    67  			fs := tools.Parameter{
    68  				Name:  "filesystem",
    69  				Value: "bind",
    70  			}
    71  			if tmpfs {
    72  				fs.Value = "tmpfs"
    73  			}
    74  			name, err := tools.ParametersToName(fsize, threads, fs)
    75  			if err != nil {
    76  				b.Fatalf("Failed to parse parameters: %v", err)
    77  			}
    78  			b.Run(name, func(b *testing.B) {
    79  				hey := &tools.Hey{
    80  					Requests:    b.N,
    81  					Concurrency: c,
    82  					Doc:         filename,
    83  				}
    84  				runNginx(b, hey, tmpfs)
    85  			})
    86  		}
    87  	}
    88  }
    89  
    90  // benchmarkNginxContinuous iterates through given sizes and concurrencies on a tmpfs mount.
    91  func benchmarkNginxContinuous(b *testing.B, concurrency []int, sizes []string) {
    92  	for _, size := range sizes {
    93  		filename := nginxDocs[size]
    94  		for _, c := range concurrency {
    95  			fsize := tools.Parameter{
    96  				Name:  "filesize",
    97  				Value: size,
    98  			}
    99  
   100  			threads := tools.Parameter{
   101  				Name:  "concurrency",
   102  				Value: strconv.Itoa(c),
   103  			}
   104  
   105  			fs := tools.Parameter{
   106  				Name:  "filesystem",
   107  				Value: "tmpfs",
   108  			}
   109  
   110  			name, err := tools.ParametersToName(fsize, threads, fs)
   111  			if err != nil {
   112  				b.Fatalf("Failed to parse parameters: %v", err)
   113  			}
   114  			b.Run(name, func(b *testing.B) {
   115  				hey := &tools.Hey{
   116  					Requests:    b.N,
   117  					Concurrency: c,
   118  					Doc:         filename,
   119  				}
   120  				runNginx(b, hey, true /*tmpfs*/)
   121  			})
   122  		}
   123  	}
   124  }
   125  
   126  // runNginx configures the static serving methods to run httpd.
   127  func runNginx(b *testing.B, hey *tools.Hey, tmpfs bool) {
   128  	// nginx runs on port 80.
   129  	port := 80
   130  	nginxRunOpts := dockerutil.RunOpts{
   131  		Image: "benchmarks/nginx",
   132  		Ports: []int{port},
   133  	}
   134  
   135  	nginxCmd := []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"}
   136  	if tmpfs {
   137  		nginxCmd = []string{"sh", "-c", "mkdir -p /tmp/html && cp -a /local/* /tmp/html && nginx -c /etc/nginx/nginx.conf"}
   138  	}
   139  
   140  	// Command copies nginxDocs to tmpfs serving directory and runs nginx.
   141  	runStaticServer(b, nginxRunOpts, nginxCmd, port, hey)
   142  }
   143  
   144  func TestMain(m *testing.M) {
   145  	harness.Init()
   146  	os.Exit(m.Run())
   147  }