github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/fuse/ipns/ipns_test.go (about) 1 package ipns 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "io/ioutil" 7 "os" 8 "strings" 9 "testing" 10 "time" 11 12 fstest "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil" 13 core "github.com/jbenet/go-ipfs/core" 14 u "github.com/jbenet/go-ipfs/util" 15 ) 16 17 func maybeSkipFuseTests(t *testing.T) bool { 18 v := "TEST_NO_FUSE" 19 n := strings.ToLower(os.Getenv(v)) 20 skip := n != "" && n != "false" && n != "f" 21 22 if skip { 23 t.Skipf("Skipping FUSE tests (%s=%s)", v, n) 24 } 25 return skip 26 } 27 28 func randBytes(size int) []byte { 29 b := make([]byte, size) 30 rand.Read(b) 31 return b 32 } 33 34 func writeFile(t *testing.T, size int, path string) []byte { 35 return writeFileData(t, randBytes(size), path) 36 } 37 38 func writeFileData(t *testing.T, data []byte, path string) []byte { 39 fi, err := os.Create(path) 40 if err != nil { 41 t.Fatal(err) 42 } 43 44 n, err := fi.Write(data) 45 if err != nil { 46 t.Fatal(err) 47 } 48 49 if n != len(data) { 50 t.Fatal("Didnt write proper amount!") 51 } 52 53 err = fi.Close() 54 if err != nil { 55 t.Fatal(err) 56 } 57 58 return data 59 } 60 61 func setupIpnsTest(t *testing.T, node *core.IpfsNode) (*core.IpfsNode, *fstest.Mount) { 62 maybeSkipFuseTests(t) 63 64 var err error 65 if node == nil { 66 node, err = core.NewMockNode() 67 if err != nil { 68 t.Fatal(err) 69 } 70 } 71 72 fs, err := NewIpns(node, "") 73 if err != nil { 74 t.Fatal(err) 75 } 76 mnt, err := fstest.MountedT(t, fs) 77 if err != nil { 78 t.Fatal(err) 79 } 80 81 return node, mnt 82 } 83 84 // Test writing a file and reading it back 85 func TestIpnsBasicIO(t *testing.T) { 86 _, mnt := setupIpnsTest(t, nil) 87 defer mnt.Close() 88 89 fname := mnt.Dir + "/local/testfile" 90 data := writeFile(t, 12345, fname) 91 92 rbuf, err := ioutil.ReadFile(fname) 93 if err != nil { 94 t.Fatal(err) 95 } 96 97 if !bytes.Equal(rbuf, data) { 98 t.Fatal("Incorrect Read!") 99 } 100 } 101 102 // Test to make sure file changes persist over mounts of ipns 103 func TestFilePersistence(t *testing.T) { 104 node, mnt := setupIpnsTest(t, nil) 105 106 fname := "/local/atestfile" 107 data := writeFile(t, 127, mnt.Dir+fname) 108 109 // Wait for publish: TODO: make publish happen faster in tests 110 time.Sleep(time.Millisecond * 40) 111 112 mnt.Close() 113 114 node, mnt = setupIpnsTest(t, node) 115 defer mnt.Close() 116 117 rbuf, err := ioutil.ReadFile(mnt.Dir + fname) 118 if err != nil { 119 t.Fatal(err) 120 } 121 122 if !bytes.Equal(rbuf, data) { 123 t.Fatalf("File data changed between mounts! sizes differ: %d != %d", len(data), len(rbuf)) 124 } 125 } 126 127 // Test to make sure the filesystem reports file sizes correctly 128 func TestFileSizeReporting(t *testing.T) { 129 _, mnt := setupIpnsTest(t, nil) 130 defer mnt.Close() 131 132 fname := mnt.Dir + "/local/sizecheck" 133 data := writeFile(t, 5555, fname) 134 135 finfo, err := os.Stat(fname) 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 if finfo.Size() != int64(len(data)) { 141 t.Fatal("Read incorrect size from stat!") 142 } 143 } 144 145 // Test to make sure you cant create multiple entries with the same name 146 func TestDoubleEntryFailure(t *testing.T) { 147 _, mnt := setupIpnsTest(t, nil) 148 defer mnt.Close() 149 150 dname := mnt.Dir + "/local/thisisadir" 151 err := os.Mkdir(dname, 0777) 152 if err != nil { 153 t.Fatal(err) 154 } 155 156 err = os.Mkdir(dname, 0777) 157 if err == nil { 158 t.Fatal("Should have gotten error one creating new directory.") 159 } 160 } 161 162 func TestAppendFile(t *testing.T) { 163 _, mnt := setupIpnsTest(t, nil) 164 defer mnt.Close() 165 166 fname := mnt.Dir + "/local/file" 167 data := writeFile(t, 1300, fname) 168 169 fi, err := os.OpenFile(fname, os.O_RDWR|os.O_APPEND, 0666) 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 nudata := randBytes(500) 175 176 n, err := fi.Write(nudata) 177 if err != nil { 178 t.Fatal(err) 179 } 180 err = fi.Close() 181 if err != nil { 182 t.Fatal(err) 183 } 184 185 if n != len(nudata) { 186 t.Fatal("Failed to write enough bytes.") 187 } 188 189 data = append(data, nudata...) 190 191 rbuf, err := ioutil.ReadFile(fname) 192 if err != nil { 193 t.Fatal(err) 194 } 195 if !bytes.Equal(rbuf, data) { 196 t.Fatal("Data inconsistent!") 197 } 198 } 199 200 func TestFastRepublish(t *testing.T) { 201 202 // make timeout noticeable. 203 osrt := shortRepublishTimeout 204 shortRepublishTimeout = time.Millisecond * 100 205 206 olrt := longRepublishTimeout 207 longRepublishTimeout = time.Second 208 209 node, mnt := setupIpnsTest(t, nil) 210 211 h, err := node.Identity.PrivKey().GetPublic().Hash() 212 if err != nil { 213 t.Fatal(err) 214 } 215 pubkeyHash := u.Key(h).Pretty() 216 217 // set them back 218 defer func() { 219 shortRepublishTimeout = osrt 220 longRepublishTimeout = olrt 221 mnt.Close() 222 }() 223 224 closed := make(chan struct{}) 225 dataA := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 226 dataB := []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") 227 228 fname := mnt.Dir + "/local/file" 229 230 // get first resolved hash 231 log.Debug("publishing first hash") 232 writeFileData(t, dataA, fname) // random 233 <-time.After(shortRepublishTimeout * 11 / 10) 234 log.Debug("resolving first hash") 235 resolvedHash, err := node.Namesys.Resolve(pubkeyHash) 236 if err != nil { 237 t.Fatal("resolve err:", pubkeyHash, err) 238 } 239 240 // constantly keep writing to the file 241 go func(timeout time.Duration) { 242 for { 243 select { 244 case <-closed: 245 return 246 247 case <-time.After(timeout * 8 / 10): 248 writeFileData(t, dataB, fname) 249 } 250 } 251 }(shortRepublishTimeout) 252 253 hasPublished := func() bool { 254 res, err := node.Namesys.Resolve(pubkeyHash) 255 if err != nil { 256 t.Fatalf("resolve err: %v", err) 257 } 258 return res != resolvedHash 259 } 260 261 // test things 262 263 // at this point, should not have written dataA and not have written dataB 264 rbuf, err := ioutil.ReadFile(fname) 265 if err != nil || !bytes.Equal(rbuf, dataA) { 266 t.Fatalf("Data inconsistent! %v %v", err, string(rbuf)) 267 } 268 269 if hasPublished() { 270 t.Fatal("published (wrote)") 271 } 272 273 <-time.After(shortRepublishTimeout * 11 / 10) 274 275 // at this point, should have written written dataB, but not published it 276 rbuf, err = ioutil.ReadFile(fname) 277 if err != nil || !bytes.Equal(rbuf, dataB) { 278 t.Fatalf("Data inconsistent! %v %v", err, string(rbuf)) 279 } 280 281 if hasPublished() { 282 t.Fatal("published (wrote)") 283 } 284 285 <-time.After(longRepublishTimeout * 11 / 10) 286 287 // at this point, should have written written dataB, and published it 288 rbuf, err = ioutil.ReadFile(fname) 289 if err != nil || !bytes.Equal(rbuf, dataB) { 290 t.Fatalf("Data inconsistent! %v %v", err, string(rbuf)) 291 } 292 293 if !hasPublished() { 294 t.Fatal("not published") 295 } 296 297 close(closed) 298 } 299 300 // Test writing a medium sized file one byte at a time 301 func TestMultiWrite(t *testing.T) { 302 303 _, mnt := setupIpnsTest(t, nil) 304 defer mnt.Close() 305 306 fpath := mnt.Dir + "/local/file" 307 fi, err := os.Create(fpath) 308 if err != nil { 309 t.Fatal(err) 310 } 311 312 data := randBytes(1001) 313 for i := 0; i < len(data); i++ { 314 n, err := fi.Write(data[i : i+1]) 315 if err != nil { 316 t.Fatal(err) 317 } 318 if n != 1 { 319 t.Fatal("Somehow wrote the wrong number of bytes! (n != 1)") 320 } 321 } 322 fi.Close() 323 324 rbuf, err := ioutil.ReadFile(fpath) 325 if err != nil { 326 t.Fatal(err) 327 } 328 329 if !bytes.Equal(rbuf, data) { 330 t.Fatal("File on disk did not match bytes written") 331 } 332 }