gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/network/httpd_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/httpd'.
    27  var httpdDocs = 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  // BenchmarkHttpd iterates over different sized payloads and concurrency, testing
    37  // how well the runtime handles sending different payload sizes.
    38  func BenchmarkHttpd(b *testing.B) {
    39  	benchmarkHttpdDocSize(b)
    40  }
    41  
    42  // BenchmarkContinuousHttpd runs specific benchmarks for continous jobs.
    43  // The runtime under test is the server serving a runc client.
    44  func BenchmarkContinuousHttpd(b *testing.B) {
    45  	sizes := []string{"10Kb", "100Kb", "1Mb"}
    46  	threads := []int{1, 25, 100, 1000}
    47  	benchmarkHttpdContinuous(b, threads, sizes)
    48  }
    49  
    50  // benchmarkHttpdDocSize iterates through all doc sizes, running subbenchmarks
    51  // for each size.
    52  func benchmarkHttpdDocSize(b *testing.B) {
    53  	b.Helper()
    54  	for size, filename := range httpdDocs {
    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  			concurrency := tools.Parameter{
    62  				Name:  "concurrency",
    63  				Value: strconv.Itoa(c),
    64  			}
    65  			name, err := tools.ParametersToName(fsize, concurrency)
    66  			if err != nil {
    67  				b.Fatalf("Failed to parse parameters: %v", err)
    68  			}
    69  			b.Run(name, func(b *testing.B) {
    70  				hey := &tools.Hey{
    71  					Requests:    b.N,
    72  					Concurrency: c,
    73  					Doc:         filename,
    74  				}
    75  				runHttpd(b, hey)
    76  			})
    77  		}
    78  	}
    79  }
    80  
    81  // benchmarkHttpdContinuous iterates through given sizes and concurrencies.
    82  func benchmarkHttpdContinuous(b *testing.B, concurrency []int, sizes []string) {
    83  	for _, size := range sizes {
    84  		filename := httpdDocs[size]
    85  		for _, c := range concurrency {
    86  			fsize := tools.Parameter{
    87  				Name:  "filesize",
    88  				Value: size,
    89  			}
    90  
    91  			threads := tools.Parameter{
    92  				Name:  "concurrency",
    93  				Value: strconv.Itoa(c),
    94  			}
    95  
    96  			name, err := tools.ParametersToName(fsize, threads)
    97  			if err != nil {
    98  				b.Fatalf("Failed to parse parameters: %v", err)
    99  			}
   100  			b.Run(name, func(b *testing.B) {
   101  				hey := &tools.Hey{
   102  					Requests:    b.N,
   103  					Concurrency: c,
   104  					Doc:         filename,
   105  				}
   106  				runHttpd(b, hey)
   107  			})
   108  		}
   109  	}
   110  }
   111  
   112  // runHttpd configures the static serving methods to run httpd.
   113  func runHttpd(b *testing.B, hey *tools.Hey) {
   114  	// httpd runs on port 80.
   115  	port := 80
   116  	httpdRunOpts := dockerutil.RunOpts{
   117  		Image: "benchmarks/httpd",
   118  		Ports: []int{port},
   119  		Env: []string{
   120  			// Standard environmental variables for httpd.
   121  			"APACHE_RUN_DIR=/tmp",
   122  			"APACHE_RUN_USER=nobody",
   123  			"APACHE_RUN_GROUP=nogroup",
   124  			"APACHE_LOG_DIR=/tmp",
   125  			"APACHE_PID_FILE=/tmp/apache.pid",
   126  		},
   127  	}
   128  	httpdCmd := []string{"sh", "-c", "mkdir -p /tmp/html; cp -r /local/* /tmp/html/.; apache2 -X"}
   129  	runStaticServer(b, httpdRunOpts, httpdCmd, port, hey)
   130  }
   131  
   132  func TestMain(m *testing.M) {
   133  	harness.Init()
   134  	os.Exit(m.Run())
   135  }