aufs_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. // +build linux
  2. package aufs
  3. import (
  4. "crypto/sha256"
  5. "encoding/hex"
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "path"
  10. "sync"
  11. "testing"
  12. "github.com/docker/docker/daemon/graphdriver"
  13. "github.com/docker/docker/pkg/archive"
  14. "github.com/docker/docker/pkg/reexec"
  15. "github.com/docker/docker/pkg/stringid"
  16. )
  17. var (
  18. tmpOuter = path.Join(os.TempDir(), "aufs-tests")
  19. tmp = path.Join(tmpOuter, "aufs")
  20. )
  21. func init() {
  22. reexec.Init()
  23. }
  24. func testInit(dir string, t testing.TB) graphdriver.Driver {
  25. d, err := Init(dir, nil, nil, nil)
  26. if err != nil {
  27. if err == graphdriver.ErrNotSupported {
  28. t.Skip(err)
  29. } else {
  30. t.Fatal(err)
  31. }
  32. }
  33. return d
  34. }
  35. func newDriver(t testing.TB) *Driver {
  36. if err := os.MkdirAll(tmp, 0755); err != nil {
  37. t.Fatal(err)
  38. }
  39. d := testInit(tmp, t)
  40. return d.(*Driver)
  41. }
  42. func TestNewDriver(t *testing.T) {
  43. if err := os.MkdirAll(tmp, 0755); err != nil {
  44. t.Fatal(err)
  45. }
  46. d := testInit(tmp, t)
  47. defer os.RemoveAll(tmp)
  48. if d == nil {
  49. t.Fatalf("Driver should not be nil")
  50. }
  51. }
  52. func TestAufsString(t *testing.T) {
  53. d := newDriver(t)
  54. defer os.RemoveAll(tmp)
  55. if d.String() != "aufs" {
  56. t.Fatalf("Expected aufs got %s", d.String())
  57. }
  58. }
  59. func TestCreateDirStructure(t *testing.T) {
  60. newDriver(t)
  61. defer os.RemoveAll(tmp)
  62. paths := []string{
  63. "mnt",
  64. "layers",
  65. "diff",
  66. }
  67. for _, p := range paths {
  68. if _, err := os.Stat(path.Join(tmp, p)); err != nil {
  69. t.Fatal(err)
  70. }
  71. }
  72. }
  73. // We should be able to create two drivers with the same dir structure
  74. func TestNewDriverFromExistingDir(t *testing.T) {
  75. if err := os.MkdirAll(tmp, 0755); err != nil {
  76. t.Fatal(err)
  77. }
  78. testInit(tmp, t)
  79. testInit(tmp, t)
  80. os.RemoveAll(tmp)
  81. }
  82. func TestCreateNewDir(t *testing.T) {
  83. d := newDriver(t)
  84. defer os.RemoveAll(tmp)
  85. if err := d.Create("1", "", "", nil); err != nil {
  86. t.Fatal(err)
  87. }
  88. }
  89. func TestCreateNewDirStructure(t *testing.T) {
  90. d := newDriver(t)
  91. defer os.RemoveAll(tmp)
  92. if err := d.Create("1", "", "", nil); err != nil {
  93. t.Fatal(err)
  94. }
  95. paths := []string{
  96. "mnt",
  97. "diff",
  98. "layers",
  99. }
  100. for _, p := range paths {
  101. if _, err := os.Stat(path.Join(tmp, p, "1")); err != nil {
  102. t.Fatal(err)
  103. }
  104. }
  105. }
  106. func TestRemoveImage(t *testing.T) {
  107. d := newDriver(t)
  108. defer os.RemoveAll(tmp)
  109. if err := d.Create("1", "", "", nil); err != nil {
  110. t.Fatal(err)
  111. }
  112. if err := d.Remove("1"); err != nil {
  113. t.Fatal(err)
  114. }
  115. paths := []string{
  116. "mnt",
  117. "diff",
  118. "layers",
  119. }
  120. for _, p := range paths {
  121. if _, err := os.Stat(path.Join(tmp, p, "1")); err == nil {
  122. t.Fatalf("Error should not be nil because dirs with id 1 should be delted: %s", p)
  123. }
  124. }
  125. }
  126. func TestGetWithoutParent(t *testing.T) {
  127. d := newDriver(t)
  128. defer os.RemoveAll(tmp)
  129. if err := d.Create("1", "", "", nil); err != nil {
  130. t.Fatal(err)
  131. }
  132. diffPath, err := d.Get("1", "")
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. expected := path.Join(tmp, "diff", "1")
  137. if diffPath != expected {
  138. t.Fatalf("Expected path %s got %s", expected, diffPath)
  139. }
  140. }
  141. func TestCleanupWithNoDirs(t *testing.T) {
  142. d := newDriver(t)
  143. defer os.RemoveAll(tmp)
  144. if err := d.Cleanup(); err != nil {
  145. t.Fatal(err)
  146. }
  147. }
  148. func TestCleanupWithDir(t *testing.T) {
  149. d := newDriver(t)
  150. defer os.RemoveAll(tmp)
  151. if err := d.Create("1", "", "", nil); err != nil {
  152. t.Fatal(err)
  153. }
  154. if err := d.Cleanup(); err != nil {
  155. t.Fatal(err)
  156. }
  157. }
  158. func TestMountedFalseResponse(t *testing.T) {
  159. d := newDriver(t)
  160. defer os.RemoveAll(tmp)
  161. if err := d.Create("1", "", "", nil); err != nil {
  162. t.Fatal(err)
  163. }
  164. response, err := d.mounted(d.getDiffPath("1"))
  165. if err != nil {
  166. t.Fatal(err)
  167. }
  168. if response != false {
  169. t.Fatalf("Response if dir id 1 is mounted should be false")
  170. }
  171. }
  172. func TestMountedTrueReponse(t *testing.T) {
  173. d := newDriver(t)
  174. defer os.RemoveAll(tmp)
  175. defer d.Cleanup()
  176. if err := d.Create("1", "", "", nil); err != nil {
  177. t.Fatal(err)
  178. }
  179. if err := d.Create("2", "1", "", nil); err != nil {
  180. t.Fatal(err)
  181. }
  182. _, err := d.Get("2", "")
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. response, err := d.mounted(d.pathCache["2"])
  187. if err != nil {
  188. t.Fatal(err)
  189. }
  190. if response != true {
  191. t.Fatalf("Response if dir id 2 is mounted should be true")
  192. }
  193. }
  194. func TestMountWithParent(t *testing.T) {
  195. d := newDriver(t)
  196. defer os.RemoveAll(tmp)
  197. if err := d.Create("1", "", "", nil); err != nil {
  198. t.Fatal(err)
  199. }
  200. if err := d.Create("2", "1", "", nil); err != nil {
  201. t.Fatal(err)
  202. }
  203. defer func() {
  204. if err := d.Cleanup(); err != nil {
  205. t.Fatal(err)
  206. }
  207. }()
  208. mntPath, err := d.Get("2", "")
  209. if err != nil {
  210. t.Fatal(err)
  211. }
  212. if mntPath == "" {
  213. t.Fatal("mntPath should not be empty string")
  214. }
  215. expected := path.Join(tmp, "mnt", "2")
  216. if mntPath != expected {
  217. t.Fatalf("Expected %s got %s", expected, mntPath)
  218. }
  219. }
  220. func TestRemoveMountedDir(t *testing.T) {
  221. d := newDriver(t)
  222. defer os.RemoveAll(tmp)
  223. if err := d.Create("1", "", "", nil); err != nil {
  224. t.Fatal(err)
  225. }
  226. if err := d.Create("2", "1", "", nil); err != nil {
  227. t.Fatal(err)
  228. }
  229. defer func() {
  230. if err := d.Cleanup(); err != nil {
  231. t.Fatal(err)
  232. }
  233. }()
  234. mntPath, err := d.Get("2", "")
  235. if err != nil {
  236. t.Fatal(err)
  237. }
  238. if mntPath == "" {
  239. t.Fatal("mntPath should not be empty string")
  240. }
  241. mounted, err := d.mounted(d.pathCache["2"])
  242. if err != nil {
  243. t.Fatal(err)
  244. }
  245. if !mounted {
  246. t.Fatalf("Dir id 2 should be mounted")
  247. }
  248. if err := d.Remove("2"); err != nil {
  249. t.Fatal(err)
  250. }
  251. }
  252. func TestCreateWithInvalidParent(t *testing.T) {
  253. d := newDriver(t)
  254. defer os.RemoveAll(tmp)
  255. if err := d.Create("1", "docker", "", nil); err == nil {
  256. t.Fatalf("Error should not be nil with parent does not exist")
  257. }
  258. }
  259. func TestGetDiff(t *testing.T) {
  260. d := newDriver(t)
  261. defer os.RemoveAll(tmp)
  262. if err := d.CreateReadWrite("1", "", "", nil); err != nil {
  263. t.Fatal(err)
  264. }
  265. diffPath, err := d.Get("1", "")
  266. if err != nil {
  267. t.Fatal(err)
  268. }
  269. // Add a file to the diff path with a fixed size
  270. size := int64(1024)
  271. f, err := os.Create(path.Join(diffPath, "test_file"))
  272. if err != nil {
  273. t.Fatal(err)
  274. }
  275. if err := f.Truncate(size); err != nil {
  276. t.Fatal(err)
  277. }
  278. f.Close()
  279. a, err := d.Diff("1", "")
  280. if err != nil {
  281. t.Fatal(err)
  282. }
  283. if a == nil {
  284. t.Fatalf("Archive should not be nil")
  285. }
  286. }
  287. func TestChanges(t *testing.T) {
  288. d := newDriver(t)
  289. defer os.RemoveAll(tmp)
  290. if err := d.Create("1", "", "", nil); err != nil {
  291. t.Fatal(err)
  292. }
  293. if err := d.CreateReadWrite("2", "1", "", nil); err != nil {
  294. t.Fatal(err)
  295. }
  296. defer func() {
  297. if err := d.Cleanup(); err != nil {
  298. t.Fatal(err)
  299. }
  300. }()
  301. mntPoint, err := d.Get("2", "")
  302. if err != nil {
  303. t.Fatal(err)
  304. }
  305. // Create a file to save in the mountpoint
  306. f, err := os.Create(path.Join(mntPoint, "test.txt"))
  307. if err != nil {
  308. t.Fatal(err)
  309. }
  310. if _, err := f.WriteString("testline"); err != nil {
  311. t.Fatal(err)
  312. }
  313. if err := f.Close(); err != nil {
  314. t.Fatal(err)
  315. }
  316. changes, err := d.Changes("2", "")
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. if len(changes) != 1 {
  321. t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
  322. }
  323. change := changes[0]
  324. expectedPath := "/test.txt"
  325. if change.Path != expectedPath {
  326. t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
  327. }
  328. if change.Kind != archive.ChangeAdd {
  329. t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
  330. }
  331. if err := d.CreateReadWrite("3", "2", "", nil); err != nil {
  332. t.Fatal(err)
  333. }
  334. mntPoint, err = d.Get("3", "")
  335. if err != nil {
  336. t.Fatal(err)
  337. }
  338. // Create a file to save in the mountpoint
  339. f, err = os.Create(path.Join(mntPoint, "test2.txt"))
  340. if err != nil {
  341. t.Fatal(err)
  342. }
  343. if _, err := f.WriteString("testline"); err != nil {
  344. t.Fatal(err)
  345. }
  346. if err := f.Close(); err != nil {
  347. t.Fatal(err)
  348. }
  349. changes, err = d.Changes("3", "")
  350. if err != nil {
  351. t.Fatal(err)
  352. }
  353. if len(changes) != 1 {
  354. t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
  355. }
  356. change = changes[0]
  357. expectedPath = "/test2.txt"
  358. if change.Path != expectedPath {
  359. t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
  360. }
  361. if change.Kind != archive.ChangeAdd {
  362. t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
  363. }
  364. }
  365. func TestDiffSize(t *testing.T) {
  366. d := newDriver(t)
  367. defer os.RemoveAll(tmp)
  368. if err := d.CreateReadWrite("1", "", "", nil); err != nil {
  369. t.Fatal(err)
  370. }
  371. diffPath, err := d.Get("1", "")
  372. if err != nil {
  373. t.Fatal(err)
  374. }
  375. // Add a file to the diff path with a fixed size
  376. size := int64(1024)
  377. f, err := os.Create(path.Join(diffPath, "test_file"))
  378. if err != nil {
  379. t.Fatal(err)
  380. }
  381. if err := f.Truncate(size); err != nil {
  382. t.Fatal(err)
  383. }
  384. s, err := f.Stat()
  385. if err != nil {
  386. t.Fatal(err)
  387. }
  388. size = s.Size()
  389. if err := f.Close(); err != nil {
  390. t.Fatal(err)
  391. }
  392. diffSize, err := d.DiffSize("1", "")
  393. if err != nil {
  394. t.Fatal(err)
  395. }
  396. if diffSize != size {
  397. t.Fatalf("Expected size to be %d got %d", size, diffSize)
  398. }
  399. }
  400. func TestChildDiffSize(t *testing.T) {
  401. d := newDriver(t)
  402. defer os.RemoveAll(tmp)
  403. defer d.Cleanup()
  404. if err := d.CreateReadWrite("1", "", "", nil); err != nil {
  405. t.Fatal(err)
  406. }
  407. diffPath, err := d.Get("1", "")
  408. if err != nil {
  409. t.Fatal(err)
  410. }
  411. // Add a file to the diff path with a fixed size
  412. size := int64(1024)
  413. f, err := os.Create(path.Join(diffPath, "test_file"))
  414. if err != nil {
  415. t.Fatal(err)
  416. }
  417. if err := f.Truncate(size); err != nil {
  418. t.Fatal(err)
  419. }
  420. s, err := f.Stat()
  421. if err != nil {
  422. t.Fatal(err)
  423. }
  424. size = s.Size()
  425. if err := f.Close(); err != nil {
  426. t.Fatal(err)
  427. }
  428. diffSize, err := d.DiffSize("1", "")
  429. if err != nil {
  430. t.Fatal(err)
  431. }
  432. if diffSize != size {
  433. t.Fatalf("Expected size to be %d got %d", size, diffSize)
  434. }
  435. if err := d.Create("2", "1", "", nil); err != nil {
  436. t.Fatal(err)
  437. }
  438. diffSize, err = d.DiffSize("2", "")
  439. if err != nil {
  440. t.Fatal(err)
  441. }
  442. // The diff size for the child should be zero
  443. if diffSize != 0 {
  444. t.Fatalf("Expected size to be %d got %d", 0, diffSize)
  445. }
  446. }
  447. func TestExists(t *testing.T) {
  448. d := newDriver(t)
  449. defer os.RemoveAll(tmp)
  450. defer d.Cleanup()
  451. if err := d.Create("1", "", "", nil); err != nil {
  452. t.Fatal(err)
  453. }
  454. if d.Exists("none") {
  455. t.Fatal("id name should not exist in the driver")
  456. }
  457. if !d.Exists("1") {
  458. t.Fatal("id 1 should exist in the driver")
  459. }
  460. }
  461. func TestStatus(t *testing.T) {
  462. d := newDriver(t)
  463. defer os.RemoveAll(tmp)
  464. defer d.Cleanup()
  465. if err := d.Create("1", "", "", nil); err != nil {
  466. t.Fatal(err)
  467. }
  468. status := d.Status()
  469. if status == nil || len(status) == 0 {
  470. t.Fatal("Status should not be nil or empty")
  471. }
  472. rootDir := status[0]
  473. dirs := status[2]
  474. if rootDir[0] != "Root Dir" {
  475. t.Fatalf("Expected Root Dir got %s", rootDir[0])
  476. }
  477. if rootDir[1] != d.rootPath() {
  478. t.Fatalf("Expected %s got %s", d.rootPath(), rootDir[1])
  479. }
  480. if dirs[0] != "Dirs" {
  481. t.Fatalf("Expected Dirs got %s", dirs[0])
  482. }
  483. if dirs[1] != "1" {
  484. t.Fatalf("Expected 1 got %s", dirs[1])
  485. }
  486. }
  487. func TestApplyDiff(t *testing.T) {
  488. d := newDriver(t)
  489. defer os.RemoveAll(tmp)
  490. defer d.Cleanup()
  491. if err := d.CreateReadWrite("1", "", "", nil); err != nil {
  492. t.Fatal(err)
  493. }
  494. diffPath, err := d.Get("1", "")
  495. if err != nil {
  496. t.Fatal(err)
  497. }
  498. // Add a file to the diff path with a fixed size
  499. size := int64(1024)
  500. f, err := os.Create(path.Join(diffPath, "test_file"))
  501. if err != nil {
  502. t.Fatal(err)
  503. }
  504. if err := f.Truncate(size); err != nil {
  505. t.Fatal(err)
  506. }
  507. f.Close()
  508. diff, err := d.Diff("1", "")
  509. if err != nil {
  510. t.Fatal(err)
  511. }
  512. if err := d.Create("2", "", "", nil); err != nil {
  513. t.Fatal(err)
  514. }
  515. if err := d.Create("3", "2", "", nil); err != nil {
  516. t.Fatal(err)
  517. }
  518. if err := d.applyDiff("3", diff); err != nil {
  519. t.Fatal(err)
  520. }
  521. // Ensure that the file is in the mount point for id 3
  522. mountPoint, err := d.Get("3", "")
  523. if err != nil {
  524. t.Fatal(err)
  525. }
  526. if _, err := os.Stat(path.Join(mountPoint, "test_file")); err != nil {
  527. t.Fatal(err)
  528. }
  529. }
  530. func hash(c string) string {
  531. h := sha256.New()
  532. fmt.Fprint(h, c)
  533. return hex.EncodeToString(h.Sum(nil))
  534. }
  535. func testMountMoreThan42Layers(t *testing.T, mountPath string) {
  536. if err := os.MkdirAll(mountPath, 0755); err != nil {
  537. t.Fatal(err)
  538. }
  539. defer os.RemoveAll(mountPath)
  540. d := testInit(mountPath, t).(*Driver)
  541. defer d.Cleanup()
  542. var last string
  543. var expected int
  544. for i := 1; i < 127; i++ {
  545. expected++
  546. var (
  547. parent = fmt.Sprintf("%d", i-1)
  548. current = fmt.Sprintf("%d", i)
  549. )
  550. if parent == "0" {
  551. parent = ""
  552. } else {
  553. parent = hash(parent)
  554. }
  555. current = hash(current)
  556. if err := d.CreateReadWrite(current, parent, "", nil); err != nil {
  557. t.Logf("Current layer %d", i)
  558. t.Error(err)
  559. }
  560. point, err := d.Get(current, "")
  561. if err != nil {
  562. t.Logf("Current layer %d", i)
  563. t.Error(err)
  564. }
  565. f, err := os.Create(path.Join(point, current))
  566. if err != nil {
  567. t.Logf("Current layer %d", i)
  568. t.Error(err)
  569. }
  570. f.Close()
  571. if i%10 == 0 {
  572. if err := os.Remove(path.Join(point, parent)); err != nil {
  573. t.Logf("Current layer %d", i)
  574. t.Error(err)
  575. }
  576. expected--
  577. }
  578. last = current
  579. }
  580. // Perform the actual mount for the top most image
  581. point, err := d.Get(last, "")
  582. if err != nil {
  583. t.Error(err)
  584. }
  585. files, err := ioutil.ReadDir(point)
  586. if err != nil {
  587. t.Error(err)
  588. }
  589. if len(files) != expected {
  590. t.Errorf("Expected %d got %d", expected, len(files))
  591. }
  592. }
  593. func TestMountMoreThan42Layers(t *testing.T) {
  594. os.RemoveAll(tmpOuter)
  595. testMountMoreThan42Layers(t, tmp)
  596. }
  597. func TestMountMoreThan42LayersMatchingPathLength(t *testing.T) {
  598. defer os.RemoveAll(tmpOuter)
  599. zeroes := "0"
  600. for {
  601. // This finds a mount path so that when combined into aufs mount options
  602. // 4096 byte boundary would be in between the paths or in permission
  603. // section. For '/tmp' it will use '/tmp/aufs-tests/00000000/aufs'
  604. mountPath := path.Join(tmpOuter, zeroes, "aufs")
  605. pathLength := 77 + len(mountPath)
  606. if mod := 4095 % pathLength; mod == 0 || mod > pathLength-2 {
  607. t.Logf("Using path: %s", mountPath)
  608. testMountMoreThan42Layers(t, mountPath)
  609. return
  610. }
  611. zeroes += "0"
  612. }
  613. }
  614. func BenchmarkConcurrentAccess(b *testing.B) {
  615. b.StopTimer()
  616. b.ResetTimer()
  617. d := newDriver(b)
  618. defer os.RemoveAll(tmp)
  619. defer d.Cleanup()
  620. numConcurent := 256
  621. // create a bunch of ids
  622. var ids []string
  623. for i := 0; i < numConcurent; i++ {
  624. ids = append(ids, stringid.GenerateNonCryptoID())
  625. }
  626. if err := d.Create(ids[0], "", "", nil); err != nil {
  627. b.Fatal(err)
  628. }
  629. if err := d.Create(ids[1], ids[0], "", nil); err != nil {
  630. b.Fatal(err)
  631. }
  632. parent := ids[1]
  633. ids = append(ids[2:])
  634. chErr := make(chan error, numConcurent)
  635. var outerGroup sync.WaitGroup
  636. outerGroup.Add(len(ids))
  637. b.StartTimer()
  638. // here's the actual bench
  639. for _, id := range ids {
  640. go func(id string) {
  641. defer outerGroup.Done()
  642. if err := d.Create(id, parent, "", nil); err != nil {
  643. b.Logf("Create %s failed", id)
  644. chErr <- err
  645. return
  646. }
  647. var innerGroup sync.WaitGroup
  648. for i := 0; i < b.N; i++ {
  649. innerGroup.Add(1)
  650. go func() {
  651. d.Get(id, "")
  652. d.Put(id)
  653. innerGroup.Done()
  654. }()
  655. }
  656. innerGroup.Wait()
  657. d.Remove(id)
  658. }(id)
  659. }
  660. outerGroup.Wait()
  661. b.StopTimer()
  662. close(chErr)
  663. for err := range chErr {
  664. if err != nil {
  665. b.Log(err)
  666. b.Fail()
  667. }
  668. }
  669. }