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 }