aufs_test.go 13 KB

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