aufs_test.go 12 KB

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