github.com/scaleoutsean/fusego@v0.0.0-20220224074057-4a6429e46bb8/samples/interruptfs/interrupt_fs_test.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 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 interruptfs_test 16 17 import ( 18 "bytes" 19 "os" 20 "os/exec" 21 "path" 22 "testing" 23 "time" 24 25 "github.com/scaleoutsean/fusego/fuseutil" 26 "github.com/scaleoutsean/fusego/samples" 27 "github.com/scaleoutsean/fusego/samples/interruptfs" 28 . "github.com/jacobsa/oglematchers" 29 . "github.com/jacobsa/ogletest" 30 ) 31 32 func TestInterruptFS(t *testing.T) { RunTests(t) } 33 34 //////////////////////////////////////////////////////////////////////// 35 // Boilerplate 36 //////////////////////////////////////////////////////////////////////// 37 38 type InterruptFSTest struct { 39 samples.SampleTest 40 fs *interruptfs.InterruptFS 41 } 42 43 func init() { RegisterTestSuite(&InterruptFSTest{}) } 44 45 var _ SetUpInterface = &InterruptFSTest{} 46 var _ TearDownInterface = &InterruptFSTest{} 47 48 func (t *InterruptFSTest) SetUp(ti *TestInfo) { 49 var err error 50 51 // Create the file system. 52 t.fs = interruptfs.New() 53 AssertEq(nil, err) 54 55 t.Server = fuseutil.NewFileSystemServer(t.fs) 56 57 // Mount it. 58 t.SampleTest.SetUp(ti) 59 } 60 61 //////////////////////////////////////////////////////////////////////// 62 // Test functions 63 //////////////////////////////////////////////////////////////////////// 64 65 func (t *InterruptFSTest) StatFoo() { 66 fi, err := os.Stat(path.Join(t.Dir, "foo")) 67 AssertEq(nil, err) 68 69 ExpectEq("foo", fi.Name()) 70 ExpectEq(0777, fi.Mode()) 71 ExpectFalse(fi.IsDir()) 72 } 73 74 func (t *InterruptFSTest) InterruptedDuringRead() { 75 var err error 76 t.fs.EnableReadBlocking() 77 78 // Start a sub-process that attempts to read the file. 79 cmd := exec.Command("cat", path.Join(t.Dir, "foo")) 80 81 var cmdOutput bytes.Buffer 82 cmd.Stdout = &cmdOutput 83 cmd.Stderr = &cmdOutput 84 85 err = cmd.Start() 86 AssertEq(nil, err) 87 88 // Wait for the command in the background, writing to a channel when it is 89 // finished. 90 cmdErr := make(chan error) 91 go func() { 92 cmdErr <- cmd.Wait() 93 }() 94 95 // Wait for the read to make it to the file system. 96 t.fs.WaitForFirstRead() 97 98 // The command should be hanging on the read, and not yet have returned. 99 select { 100 case err = <-cmdErr: 101 AddFailure("Command returned early with error: %v", err) 102 AbortTest() 103 104 case <-time.After(10 * time.Millisecond): 105 } 106 107 // Send SIGINT. 108 cmd.Process.Signal(os.Interrupt) 109 110 // Now the command should return, with an appropriate error. 111 err = <-cmdErr 112 ExpectThat(err, Error(HasSubstr("signal"))) 113 ExpectThat(err, Error(HasSubstr("interrupt"))) 114 } 115 116 func (t *InterruptFSTest) InterruptedDuringFlush() { 117 var err error 118 t.fs.EnableFlushBlocking() 119 120 // Start a sub-process that attempts to read the file. 121 cmd := exec.Command("cat", path.Join(t.Dir, "foo")) 122 123 var cmdOutput bytes.Buffer 124 cmd.Stdout = &cmdOutput 125 cmd.Stderr = &cmdOutput 126 127 err = cmd.Start() 128 AssertEq(nil, err) 129 130 // Wait for the command in the background, writing to a channel when it is 131 // finished. 132 cmdErr := make(chan error) 133 go func() { 134 cmdErr <- cmd.Wait() 135 }() 136 137 // Wait for the flush to make it to the file system. 138 t.fs.WaitForFirstFlush() 139 140 // The command should be hanging on the flush, and not yet have returned. 141 select { 142 case err = <-cmdErr: 143 AddFailure("Command returned early with error: %v", err) 144 AbortTest() 145 146 case <-time.After(10 * time.Millisecond): 147 } 148 149 // Send SIGINT. 150 cmd.Process.Signal(os.Interrupt) 151 152 // Now the command should return, with an appropriate error. 153 err = <-cmdErr 154 ExpectThat(err, Error(HasSubstr("signal"))) 155 ExpectThat(err, Error(HasSubstr("interrupt"))) 156 }