github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/benchmarks/harness/util.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 15 package harness 16 17 import ( 18 "context" 19 "fmt" 20 "net" 21 "strings" 22 "testing" 23 24 "github.com/docker/docker/api/types/mount" 25 "github.com/SagerNet/gvisor/pkg/cleanup" 26 "github.com/SagerNet/gvisor/pkg/test/dockerutil" 27 "github.com/SagerNet/gvisor/pkg/test/testutil" 28 ) 29 30 //TODO(github.com/SagerNet/issue/3535): move to own package or move methods to harness struct. 31 32 // WaitUntilServing grabs a container from `machine` and waits for a server at 33 // IP:port. 34 func WaitUntilServing(ctx context.Context, machine Machine, server net.IP, port int) error { 35 var logger testutil.DefaultLogger = "util" 36 netcat := machine.GetNativeContainer(ctx, logger) 37 defer netcat.CleanUp(ctx) 38 39 cmd := fmt.Sprintf("while ! wget -q --spider http://%s:%d; do true; done", server, port) 40 _, err := netcat.Run(ctx, dockerutil.RunOpts{ 41 Image: "benchmarks/util", 42 }, "sh", "-c", cmd) 43 return err 44 } 45 46 // DropCaches drops caches on the provided machine. Requires root. 47 func DropCaches(machine Machine) error { 48 if out, err := machine.RunCommand("/bin/sh", "-c", "sync && sysctl vm.drop_caches=3"); err != nil { 49 return fmt.Errorf("failed to drop caches: %v logs: %s", err, out) 50 } 51 return nil 52 } 53 54 // DebugLog prints debug messages if the debug flag is set. 55 func DebugLog(b *testing.B, msg string, args ...interface{}) { 56 b.Helper() 57 if *debug { 58 b.Logf(msg, args...) 59 } 60 } 61 62 // FileSystemType represents a type container mount. 63 type FileSystemType string 64 65 const ( 66 // BindFS indicates a bind mount should be created. 67 BindFS FileSystemType = "bindfs" 68 // TmpFS indicates a tmpfs mount should be created. 69 TmpFS FileSystemType = "tmpfs" 70 // RootFS indicates no mount should be created and the root mount should be used. 71 RootFS FileSystemType = "rootfs" 72 ) 73 74 // MakeMount makes a mount and cleanup based on the requested type. Bind 75 // and volume mounts are backed by a temp directory made with mktemp. 76 // tmpfs mounts require no such backing and are just made. 77 // rootfs mounts do not make a mount, but instead return a target direectory at root. 78 // It is up to the caller to call Clean on the passed *cleanup.Cleanup 79 func MakeMount(machine Machine, fsType FileSystemType, cu *cleanup.Cleanup) ([]mount.Mount, string, error) { 80 mounts := make([]mount.Mount, 0, 1) 81 target := "/data" 82 switch fsType { 83 case BindFS: 84 dir, err := machine.RunCommand("mktemp", "-d") 85 if err != nil { 86 return mounts, "", fmt.Errorf("failed to create tempdir: %v", err) 87 } 88 dir = strings.TrimSuffix(dir, "\n") 89 cu.Add(func() { 90 machine.RunCommand("rm", "-rf", dir) 91 }) 92 out, err := machine.RunCommand("chmod", "777", dir) 93 if err != nil { 94 return mounts, "", fmt.Errorf("failed modify directory: %v %s", err, out) 95 } 96 mounts = append(mounts, mount.Mount{ 97 Target: target, 98 Source: dir, 99 Type: mount.TypeBind, 100 }) 101 return mounts, target, nil 102 case RootFS: 103 return mounts, target, nil 104 case TmpFS: 105 mounts = append(mounts, mount.Mount{ 106 Target: target, 107 Type: mount.TypeTmpfs, 108 }) 109 return mounts, target, nil 110 default: 111 return mounts, "", fmt.Errorf("illegal mount type not supported: %v", fsType) 112 } 113 }