gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/fsstress/fsstress_test.go (about)

     1  // Copyright 2021 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  
    15  // Package fsstress runs fsstress tool inside a docker container.
    16  package fsstress
    17  
    18  import (
    19  	"context"
    20  	"flag"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"math/rand"
    24  	"os"
    25  	"strconv"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/docker/docker/api/types/mount"
    31  	"gvisor.dev/gvisor/pkg/test/dockerutil"
    32  	"gvisor.dev/gvisor/pkg/test/testutil"
    33  )
    34  
    35  func init() {
    36  	rand.Seed(int64(time.Now().Nanosecond()))
    37  }
    38  
    39  func TestMain(m *testing.M) {
    40  	dockerutil.EnsureSupportedDockerVersion()
    41  	flag.Parse()
    42  	os.Exit(m.Run())
    43  }
    44  
    45  type config struct {
    46  	operations string
    47  	processes  string
    48  	target     string
    49  	mounts     []mount.Mount
    50  }
    51  
    52  func fsstress(t *testing.T, conf config) {
    53  	ctx := context.Background()
    54  	d := dockerutil.MakeContainer(ctx, t)
    55  	defer d.CleanUp(ctx)
    56  
    57  	const image = "basic/fsstress"
    58  	seed := strconv.FormatUint(uint64(rand.Uint32()), 10)
    59  	args := []string{"-d", conf.target, "-n", conf.operations, "-p", conf.processes, "-s", seed, "-X"}
    60  	opts := dockerutil.RunOpts{
    61  		Image:  image,
    62  		Mounts: conf.mounts,
    63  	}
    64  	var mounts string
    65  	if len(conf.mounts) > 0 {
    66  		mounts = " -v "
    67  		for _, m := range conf.mounts {
    68  			mounts += fmt.Sprintf("-v <any_dir>:%s", m.Target)
    69  		}
    70  	}
    71  	t.Logf("Repro: docker run --rm --runtime=%s%s gvisor.dev/images/%s %s", dockerutil.Runtime(), mounts, image, strings.Join(args, " "))
    72  	out, err := d.Run(ctx, opts, args...)
    73  	if err != nil {
    74  		t.Fatalf("docker run failed: %v\noutput: %s", err, out)
    75  	}
    76  	// This is to catch cases where fsstress spews out error messages during clean
    77  	// up but doesn't return error.
    78  	if len(out) > 0 {
    79  		t.Fatalf("unexpected output: %s", out)
    80  	}
    81  }
    82  
    83  func TestFsstressGofer(t *testing.T) {
    84  	// This takes between 30-60s to run on my machine. Adjust as needed.
    85  	cfg := config{
    86  		operations: "500",
    87  		processes:  "20",
    88  		target:     "/test",
    89  	}
    90  	fsstress(t, cfg)
    91  }
    92  
    93  func TestFsstressGoferShared(t *testing.T) {
    94  	dir, err := ioutil.TempDir(testutil.TmpDir(), "fsstress")
    95  	if err != nil {
    96  		t.Fatalf("ioutil.TempDir() failed: %v", err)
    97  	}
    98  	defer os.RemoveAll(dir)
    99  
   100  	// This takes between 30-60s to run on my machine. Adjust as needed.
   101  	cfg := config{
   102  		operations: "500",
   103  		processes:  "20",
   104  		target:     "/test",
   105  		mounts: []mount.Mount{
   106  			{
   107  				Source: dir,
   108  				Target: "/test",
   109  				Type:   "bind",
   110  			},
   111  		},
   112  	}
   113  	fsstress(t, cfg)
   114  }
   115  
   116  func TestFsstressTmpfs(t *testing.T) {
   117  	// This takes between 10s to run on my machine. Adjust as needed.
   118  	cfg := config{
   119  		operations: "5000",
   120  		processes:  "20",
   121  		target:     "/tmp",
   122  	}
   123  	fsstress(t, cfg)
   124  }