driver_test.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. package devmapper
  2. import (
  3. "fmt"
  4. "github.com/dotcloud/docker/graphdriver"
  5. "io/ioutil"
  6. "path"
  7. "runtime"
  8. "strings"
  9. "syscall"
  10. "testing"
  11. )
  12. func init() {
  13. // Reduce the size the the base fs and loopback for the tests
  14. DefaultDataLoopbackSize = 300 * 1024 * 1024
  15. DefaultMetaDataLoopbackSize = 200 * 1024 * 1024
  16. DefaultBaseFsSize = 300 * 1024 * 1024
  17. }
  18. // denyAllDevmapper mocks all calls to libdevmapper in the unit tests, and denies them by default
  19. func denyAllDevmapper() {
  20. // Hijack all calls to libdevmapper with default panics.
  21. // Authorized calls are selectively hijacked in each tests.
  22. DmTaskCreate = func(t int) *CDmTask {
  23. panic("DmTaskCreate: this method should not be called here")
  24. }
  25. DmTaskRun = func(task *CDmTask) int {
  26. panic("DmTaskRun: this method should not be called here")
  27. }
  28. DmTaskSetName = func(task *CDmTask, name string) int {
  29. panic("DmTaskSetName: this method should not be called here")
  30. }
  31. DmTaskSetMessage = func(task *CDmTask, message string) int {
  32. panic("DmTaskSetMessage: this method should not be called here")
  33. }
  34. DmTaskSetSector = func(task *CDmTask, sector uint64) int {
  35. panic("DmTaskSetSector: this method should not be called here")
  36. }
  37. DmTaskSetCookie = func(task *CDmTask, cookie *uint, flags uint16) int {
  38. panic("DmTaskSetCookie: this method should not be called here")
  39. }
  40. DmTaskSetAddNode = func(task *CDmTask, addNode AddNodeType) int {
  41. panic("DmTaskSetAddNode: this method should not be called here")
  42. }
  43. DmTaskSetRo = func(task *CDmTask) int {
  44. panic("DmTaskSetRo: this method should not be called here")
  45. }
  46. DmTaskAddTarget = func(task *CDmTask, start, size uint64, ttype, params string) int {
  47. panic("DmTaskAddTarget: this method should not be called here")
  48. }
  49. DmTaskGetInfo = func(task *CDmTask, info *Info) int {
  50. panic("DmTaskGetInfo: this method should not be called here")
  51. }
  52. DmGetNextTarget = func(task *CDmTask, next uintptr, start, length *uint64, target, params *string) uintptr {
  53. panic("DmGetNextTarget: this method should not be called here")
  54. }
  55. DmUdevWait = func(cookie uint) int {
  56. panic("DmUdevWait: this method should not be called here")
  57. }
  58. DmSetDevDir = func(dir string) int {
  59. panic("DmSetDevDir: this method should not be called here")
  60. }
  61. DmGetLibraryVersion = func(version *string) int {
  62. panic("DmGetLibraryVersion: this method should not be called here")
  63. }
  64. DmLogInitVerbose = func(level int) {
  65. panic("DmLogInitVerbose: this method should not be called here")
  66. }
  67. DmTaskDestroy = func(task *CDmTask) {
  68. panic("DmTaskDestroy: this method should not be called here")
  69. }
  70. LogWithErrnoInit = func() {
  71. panic("LogWithErrnoInit: this method should not be called here")
  72. }
  73. }
  74. func denyAllSyscall() {
  75. sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
  76. panic("sysMount: this method should not be called here")
  77. }
  78. sysUnmount = func(target string, flags int) (err error) {
  79. panic("sysUnmount: this method should not be called here")
  80. }
  81. sysCloseOnExec = func(fd int) {
  82. panic("sysCloseOnExec: this method should not be called here")
  83. }
  84. sysSyscall = func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
  85. panic("sysSyscall: this method should not be called here")
  86. }
  87. // Not a syscall, but forbidding it here anyway
  88. Mounted = func(mnt string) (bool, error) {
  89. panic("devmapper.Mounted: this method should not be called here")
  90. }
  91. // osOpenFile = os.OpenFile
  92. // osNewFile = os.NewFile
  93. // osCreate = os.Create
  94. // osStat = os.Stat
  95. // osIsNotExist = os.IsNotExist
  96. // osIsExist = os.IsExist
  97. // osMkdirAll = os.MkdirAll
  98. // osRemoveAll = os.RemoveAll
  99. // osRename = os.Rename
  100. // osReadlink = os.Readlink
  101. // execRun = func(name string, args ...string) error {
  102. // return exec.Command(name, args...).Run()
  103. // }
  104. }
  105. func mkTestDirectory(t *testing.T) string {
  106. dir, err := ioutil.TempDir("", "docker-test-devmapper-")
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. return dir
  111. }
  112. func newDriver(t *testing.T) *Driver {
  113. home := mkTestDirectory(t)
  114. d, err := Init(home)
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. return d.(*Driver)
  119. }
  120. func cleanup(d *Driver) {
  121. d.Cleanup()
  122. osRemoveAll(d.home)
  123. }
  124. type Set map[string]bool
  125. func (r Set) Assert(t *testing.T, names ...string) {
  126. for _, key := range names {
  127. if _, exists := r[key]; !exists {
  128. t.Fatalf("Key not set: %s", key)
  129. }
  130. delete(r, key)
  131. }
  132. if len(r) != 0 {
  133. t.Fatalf("Unexpected keys: %v", r)
  134. }
  135. }
  136. func TestInit(t *testing.T) {
  137. var (
  138. calls = make(Set)
  139. taskMessages = make(Set)
  140. taskTypes = make(Set)
  141. home = mkTestDirectory(t)
  142. )
  143. defer osRemoveAll(home)
  144. func() {
  145. denyAllDevmapper()
  146. DmSetDevDir = func(dir string) int {
  147. calls["DmSetDevDir"] = true
  148. expectedDir := "/dev"
  149. if dir != expectedDir {
  150. t.Fatalf("Wrong libdevmapper call\nExpected: DmSetDevDir(%v)\nReceived: DmSetDevDir(%v)\n", expectedDir, dir)
  151. }
  152. return 0
  153. }
  154. LogWithErrnoInit = func() {
  155. calls["DmLogWithErrnoInit"] = true
  156. }
  157. var task1 CDmTask
  158. DmTaskCreate = func(taskType int) *CDmTask {
  159. calls["DmTaskCreate"] = true
  160. taskTypes[fmt.Sprintf("%d", taskType)] = true
  161. return &task1
  162. }
  163. DmTaskSetName = func(task *CDmTask, name string) int {
  164. calls["DmTaskSetName"] = true
  165. expectedTask := &task1
  166. if task != expectedTask {
  167. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskSetName(%v)\nReceived: DmTaskSetName(%v)\n", expectedTask, task)
  168. }
  169. // FIXME: use Set.AssertRegexp()
  170. if !strings.HasPrefix(name, "docker-") && !strings.HasPrefix(name, "/dev/mapper/docker-") ||
  171. !strings.HasSuffix(name, "-pool") && !strings.HasSuffix(name, "-base") {
  172. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskSetName(%v)\nReceived: DmTaskSetName(%v)\n", "docker-...-pool", name)
  173. }
  174. return 1
  175. }
  176. DmTaskRun = func(task *CDmTask) int {
  177. calls["DmTaskRun"] = true
  178. expectedTask := &task1
  179. if task != expectedTask {
  180. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskRun(%v)\nReceived: DmTaskRun(%v)\n", expectedTask, task)
  181. }
  182. return 1
  183. }
  184. DmTaskGetInfo = func(task *CDmTask, info *Info) int {
  185. calls["DmTaskGetInfo"] = true
  186. expectedTask := &task1
  187. if task != expectedTask {
  188. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskGetInfo(%v)\nReceived: DmTaskGetInfo(%v)\n", expectedTask, task)
  189. }
  190. // This will crash if info is not dereferenceable
  191. info.Exists = 0
  192. return 1
  193. }
  194. DmTaskSetSector = func(task *CDmTask, sector uint64) int {
  195. calls["DmTaskSetSector"] = true
  196. expectedTask := &task1
  197. if task != expectedTask {
  198. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskSetSector(%v)\nReceived: DmTaskSetSector(%v)\n", expectedTask, task)
  199. }
  200. if expectedSector := uint64(0); sector != expectedSector {
  201. t.Fatalf("Wrong libdevmapper call to DmTaskSetSector\nExpected: %v\nReceived: %v\n", expectedSector, sector)
  202. }
  203. return 1
  204. }
  205. DmTaskSetMessage = func(task *CDmTask, message string) int {
  206. calls["DmTaskSetMessage"] = true
  207. expectedTask := &task1
  208. if task != expectedTask {
  209. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskSetSector(%v)\nReceived: DmTaskSetSector(%v)\n", expectedTask, task)
  210. }
  211. taskMessages[message] = true
  212. return 1
  213. }
  214. DmTaskDestroy = func(task *CDmTask) {
  215. calls["DmTaskDestroy"] = true
  216. expectedTask := &task1
  217. if task != expectedTask {
  218. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskDestroy(%v)\nReceived: DmTaskDestroy(%v)\n", expectedTask, task)
  219. }
  220. }
  221. DmTaskAddTarget = func(task *CDmTask, start, size uint64, ttype, params string) int {
  222. calls["DmTaskSetTarget"] = true
  223. expectedTask := &task1
  224. if task != expectedTask {
  225. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskDestroy(%v)\nReceived: DmTaskDestroy(%v)\n", expectedTask, task)
  226. }
  227. if start != 0 {
  228. t.Fatalf("Wrong start: %d != %d", start, 0)
  229. }
  230. if ttype != "thin" && ttype != "thin-pool" {
  231. t.Fatalf("Wrong ttype: %s", ttype)
  232. }
  233. // Quick smoke test
  234. if params == "" {
  235. t.Fatalf("Params should not be empty")
  236. }
  237. return 1
  238. }
  239. fakeCookie := uint(4321)
  240. DmTaskSetCookie = func(task *CDmTask, cookie *uint, flags uint16) int {
  241. calls["DmTaskSetCookie"] = true
  242. expectedTask := &task1
  243. if task != expectedTask {
  244. t.Fatalf("Wrong libdevmapper call\nExpected: DmTaskDestroy(%v)\nReceived: DmTaskDestroy(%v)\n", expectedTask, task)
  245. }
  246. if flags != 0 {
  247. t.Fatalf("Cookie flags should be 0 (not %x)", flags)
  248. }
  249. *cookie = fakeCookie
  250. return 1
  251. }
  252. DmUdevWait = func(cookie uint) int {
  253. calls["DmUdevWait"] = true
  254. if cookie != fakeCookie {
  255. t.Fatalf("Wrong cookie: %d != %d", cookie, fakeCookie)
  256. }
  257. return 1
  258. }
  259. DmTaskSetAddNode = func(task *CDmTask, addNode AddNodeType) int {
  260. if addNode != AddNodeOnCreate {
  261. t.Fatalf("Wrong AddNoteType: %v (expected %v)", addNode, AddNodeOnCreate)
  262. }
  263. calls["DmTaskSetAddNode"] = true
  264. return 1
  265. }
  266. execRun = func(name string, args ...string) error {
  267. calls["execRun"] = true
  268. if name != "mkfs.ext4" {
  269. t.Fatalf("Expected %s to be executed, not %s", "mkfs.ext4", name)
  270. }
  271. return nil
  272. }
  273. driver, err := Init(home)
  274. if err != nil {
  275. t.Fatal(err)
  276. }
  277. defer func() {
  278. if err := driver.Cleanup(); err != nil {
  279. t.Fatal(err)
  280. }
  281. }()
  282. }()
  283. // Put all tests in a funciton to make sure the garbage collection will
  284. // occur.
  285. // Call GC to cleanup runtime.Finalizers
  286. runtime.GC()
  287. calls.Assert(t,
  288. "DmSetDevDir",
  289. "DmLogWithErrnoInit",
  290. "DmTaskSetName",
  291. "DmTaskRun",
  292. "DmTaskGetInfo",
  293. "DmTaskDestroy",
  294. "execRun",
  295. "DmTaskCreate",
  296. "DmTaskSetTarget",
  297. "DmTaskSetCookie",
  298. "DmUdevWait",
  299. "DmTaskSetSector",
  300. "DmTaskSetMessage",
  301. "DmTaskSetAddNode",
  302. )
  303. taskTypes.Assert(t, "0", "6", "17")
  304. taskMessages.Assert(t, "create_thin 0", "set_transaction_id 0 1")
  305. }
  306. func fakeInit() func(home string) (graphdriver.Driver, error) {
  307. oldInit := Init
  308. Init = func(home string) (graphdriver.Driver, error) {
  309. return &Driver{
  310. home: home,
  311. }, nil
  312. }
  313. return oldInit
  314. }
  315. func restoreInit(init func(home string) (graphdriver.Driver, error)) {
  316. Init = init
  317. }
  318. func mockAllDevmapper(calls Set) {
  319. DmSetDevDir = func(dir string) int {
  320. calls["DmSetDevDir"] = true
  321. return 0
  322. }
  323. LogWithErrnoInit = func() {
  324. calls["DmLogWithErrnoInit"] = true
  325. }
  326. DmTaskCreate = func(taskType int) *CDmTask {
  327. calls["DmTaskCreate"] = true
  328. return &CDmTask{}
  329. }
  330. DmTaskSetName = func(task *CDmTask, name string) int {
  331. calls["DmTaskSetName"] = true
  332. return 1
  333. }
  334. DmTaskRun = func(task *CDmTask) int {
  335. calls["DmTaskRun"] = true
  336. return 1
  337. }
  338. DmTaskGetInfo = func(task *CDmTask, info *Info) int {
  339. calls["DmTaskGetInfo"] = true
  340. return 1
  341. }
  342. DmTaskSetSector = func(task *CDmTask, sector uint64) int {
  343. calls["DmTaskSetSector"] = true
  344. return 1
  345. }
  346. DmTaskSetMessage = func(task *CDmTask, message string) int {
  347. calls["DmTaskSetMessage"] = true
  348. return 1
  349. }
  350. DmTaskDestroy = func(task *CDmTask) {
  351. calls["DmTaskDestroy"] = true
  352. }
  353. DmTaskAddTarget = func(task *CDmTask, start, size uint64, ttype, params string) int {
  354. calls["DmTaskSetTarget"] = true
  355. return 1
  356. }
  357. DmTaskSetCookie = func(task *CDmTask, cookie *uint, flags uint16) int {
  358. calls["DmTaskSetCookie"] = true
  359. return 1
  360. }
  361. DmUdevWait = func(cookie uint) int {
  362. calls["DmUdevWait"] = true
  363. return 1
  364. }
  365. DmTaskSetAddNode = func(task *CDmTask, addNode AddNodeType) int {
  366. calls["DmTaskSetAddNode"] = true
  367. return 1
  368. }
  369. execRun = func(name string, args ...string) error {
  370. calls["execRun"] = true
  371. return nil
  372. }
  373. }
  374. func TestDriverName(t *testing.T) {
  375. denyAllDevmapper()
  376. defer denyAllDevmapper()
  377. oldInit := fakeInit()
  378. defer restoreInit(oldInit)
  379. d := newDriver(t)
  380. if d.String() != "devicemapper" {
  381. t.Fatalf("Expected driver name to be devicemapper got %s", d.String())
  382. }
  383. }
  384. func TestDriverCreate(t *testing.T) {
  385. denyAllDevmapper()
  386. denyAllSyscall()
  387. defer denyAllSyscall()
  388. defer denyAllDevmapper()
  389. calls := make(Set)
  390. mockAllDevmapper(calls)
  391. sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
  392. calls["sysMount"] = true
  393. // FIXME: compare the exact source and target strings (inodes + devname)
  394. if expectedSource := "/dev/mapper/docker-"; !strings.HasPrefix(source, expectedSource) {
  395. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedSource, source)
  396. }
  397. if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
  398. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
  399. }
  400. if expectedFstype := "ext4"; fstype != expectedFstype {
  401. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFstype, fstype)
  402. }
  403. if expectedFlags := uintptr(3236757504); flags != expectedFlags {
  404. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
  405. }
  406. return nil
  407. }
  408. Mounted = func(mnt string) (bool, error) {
  409. calls["Mounted"] = true
  410. if !strings.HasPrefix(mnt, "/tmp/docker-test-devmapper-") || !strings.HasSuffix(mnt, "/mnt/1") {
  411. t.Fatalf("Wrong mounted call\nExpected: Mounted(%v)\nReceived: Mounted(%v)\n", "/tmp/docker-test-devmapper-.../mnt/1", mnt)
  412. }
  413. return false, nil
  414. }
  415. sysSyscall = func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
  416. calls["sysSyscall"] = true
  417. if trap != sysSysIoctl {
  418. t.Fatalf("Unexpected syscall. Expecting SYS_IOCTL, received: %d", trap)
  419. }
  420. switch a2 {
  421. case LoopSetFd:
  422. calls["ioctl.loopsetfd"] = true
  423. case LoopCtlGetFree:
  424. calls["ioctl.loopctlgetfree"] = true
  425. case LoopGetStatus64:
  426. calls["ioctl.loopgetstatus"] = true
  427. case LoopSetStatus64:
  428. calls["ioctl.loopsetstatus"] = true
  429. case LoopClrFd:
  430. calls["ioctl.loopclrfd"] = true
  431. case LoopSetCapacity:
  432. calls["ioctl.loopsetcapacity"] = true
  433. case BlkGetSize64:
  434. calls["ioctl.blkgetsize"] = true
  435. default:
  436. t.Fatalf("Unexpected IOCTL. Received %d", a2)
  437. }
  438. return 0, 0, 0
  439. }
  440. func() {
  441. d := newDriver(t)
  442. calls.Assert(t,
  443. "DmSetDevDir",
  444. "DmLogWithErrnoInit",
  445. "DmTaskSetName",
  446. "DmTaskRun",
  447. "DmTaskGetInfo",
  448. "execRun",
  449. "DmTaskCreate",
  450. "DmTaskSetTarget",
  451. "DmTaskSetCookie",
  452. "DmUdevWait",
  453. "DmTaskSetSector",
  454. "DmTaskSetMessage",
  455. "DmTaskSetAddNode",
  456. "sysSyscall",
  457. "ioctl.blkgetsize",
  458. "ioctl.loopsetfd",
  459. "ioctl.loopsetstatus",
  460. )
  461. if err := d.Create("1", ""); err != nil {
  462. t.Fatal(err)
  463. }
  464. calls.Assert(t,
  465. "DmTaskCreate",
  466. "DmTaskGetInfo",
  467. "sysMount",
  468. "Mounted",
  469. "DmTaskRun",
  470. "DmTaskSetTarget",
  471. "DmTaskSetSector",
  472. "DmTaskSetCookie",
  473. "DmUdevWait",
  474. "DmTaskSetName",
  475. "DmTaskSetMessage",
  476. "DmTaskSetAddNode",
  477. )
  478. }()
  479. runtime.GC()
  480. calls.Assert(t,
  481. "DmTaskDestroy",
  482. )
  483. }
  484. func TestDriverRemove(t *testing.T) {
  485. denyAllDevmapper()
  486. denyAllSyscall()
  487. defer denyAllSyscall()
  488. defer denyAllDevmapper()
  489. calls := make(Set)
  490. mockAllDevmapper(calls)
  491. sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
  492. calls["sysMount"] = true
  493. // FIXME: compare the exact source and target strings (inodes + devname)
  494. if expectedSource := "/dev/mapper/docker-"; !strings.HasPrefix(source, expectedSource) {
  495. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedSource, source)
  496. }
  497. if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
  498. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
  499. }
  500. if expectedFstype := "ext4"; fstype != expectedFstype {
  501. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFstype, fstype)
  502. }
  503. if expectedFlags := uintptr(3236757504); flags != expectedFlags {
  504. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
  505. }
  506. return nil
  507. }
  508. sysUnmount = func(target string, flags int) (err error) {
  509. calls["sysUnmount"] = true
  510. // FIXME: compare the exact source and target strings (inodes + devname)
  511. if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
  512. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
  513. }
  514. if expectedFlags := 0; flags != expectedFlags {
  515. t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
  516. }
  517. return nil
  518. }
  519. Mounted = func(mnt string) (bool, error) {
  520. calls["Mounted"] = true
  521. return false, nil
  522. }
  523. sysSyscall = func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
  524. calls["sysSyscall"] = true
  525. if trap != sysSysIoctl {
  526. t.Fatalf("Unexpected syscall. Expecting SYS_IOCTL, received: %d", trap)
  527. }
  528. switch a2 {
  529. case LoopSetFd:
  530. calls["ioctl.loopsetfd"] = true
  531. case LoopCtlGetFree:
  532. calls["ioctl.loopctlgetfree"] = true
  533. case LoopGetStatus64:
  534. calls["ioctl.loopgetstatus"] = true
  535. case LoopSetStatus64:
  536. calls["ioctl.loopsetstatus"] = true
  537. case LoopClrFd:
  538. calls["ioctl.loopclrfd"] = true
  539. case LoopSetCapacity:
  540. calls["ioctl.loopsetcapacity"] = true
  541. case BlkGetSize64:
  542. calls["ioctl.blkgetsize"] = true
  543. default:
  544. t.Fatalf("Unexpected IOCTL. Received %d", a2)
  545. }
  546. return 0, 0, 0
  547. }
  548. func() {
  549. d := newDriver(t)
  550. calls.Assert(t,
  551. "DmSetDevDir",
  552. "DmLogWithErrnoInit",
  553. "DmTaskSetName",
  554. "DmTaskRun",
  555. "DmTaskGetInfo",
  556. "execRun",
  557. "DmTaskCreate",
  558. "DmTaskSetTarget",
  559. "DmTaskSetCookie",
  560. "DmUdevWait",
  561. "DmTaskSetSector",
  562. "DmTaskSetMessage",
  563. "DmTaskSetAddNode",
  564. "sysSyscall",
  565. "ioctl.blkgetsize",
  566. "ioctl.loopsetfd",
  567. "ioctl.loopsetstatus",
  568. )
  569. if err := d.Create("1", ""); err != nil {
  570. t.Fatal(err)
  571. }
  572. calls.Assert(t,
  573. "DmTaskCreate",
  574. "DmTaskGetInfo",
  575. "sysMount",
  576. "Mounted",
  577. "DmTaskRun",
  578. "DmTaskSetTarget",
  579. "DmTaskSetSector",
  580. "DmTaskSetCookie",
  581. "DmUdevWait",
  582. "DmTaskSetName",
  583. "DmTaskSetMessage",
  584. "DmTaskSetAddNode",
  585. )
  586. Mounted = func(mnt string) (bool, error) {
  587. calls["Mounted"] = true
  588. return true, nil
  589. }
  590. if err := d.Remove("1"); err != nil {
  591. t.Fatal(err)
  592. }
  593. calls.Assert(t,
  594. "DmTaskRun",
  595. "DmTaskSetSector",
  596. "DmTaskSetName",
  597. "DmTaskSetMessage",
  598. "DmTaskCreate",
  599. "DmTaskGetInfo",
  600. "Mounted",
  601. "sysUnmount",
  602. )
  603. }()
  604. runtime.GC()
  605. calls.Assert(t,
  606. "DmTaskDestroy",
  607. )
  608. }
  609. func TestCleanup(t *testing.T) {
  610. t.Skip("FIXME: not a unit test")
  611. t.Skip("Unimplemented")
  612. d := newDriver(t)
  613. defer osRemoveAll(d.home)
  614. mountPoints := make([]string, 2)
  615. if err := d.Create("1", ""); err != nil {
  616. t.Fatal(err)
  617. }
  618. // Mount the id
  619. p, err := d.Get("1")
  620. if err != nil {
  621. t.Fatal(err)
  622. }
  623. mountPoints[0] = p
  624. if err := d.Create("2", "1"); err != nil {
  625. t.Fatal(err)
  626. }
  627. p, err = d.Get("2")
  628. if err != nil {
  629. t.Fatal(err)
  630. }
  631. mountPoints[1] = p
  632. // Ensure that all the mount points are currently mounted
  633. for _, p := range mountPoints {
  634. if mounted, err := Mounted(p); err != nil {
  635. t.Fatal(err)
  636. } else if !mounted {
  637. t.Fatalf("Expected %s to be mounted", p)
  638. }
  639. }
  640. // Ensure that devices are active
  641. for _, p := range []string{"1", "2"} {
  642. if !d.HasActivatedDevice(p) {
  643. t.Fatalf("Expected %s to have an active device", p)
  644. }
  645. }
  646. if err := d.Cleanup(); err != nil {
  647. t.Fatal(err)
  648. }
  649. // Ensure that all the mount points are no longer mounted
  650. for _, p := range mountPoints {
  651. if mounted, err := Mounted(p); err != nil {
  652. t.Fatal(err)
  653. } else if mounted {
  654. t.Fatalf("Expected %s to not be mounted", p)
  655. }
  656. }
  657. // Ensure that devices are no longer activated
  658. for _, p := range []string{"1", "2"} {
  659. if d.HasActivatedDevice(p) {
  660. t.Fatalf("Expected %s not be an active device", p)
  661. }
  662. }
  663. }
  664. func TestNotMounted(t *testing.T) {
  665. t.Skip("FIXME: not a unit test")
  666. t.Skip("Not implemented")
  667. d := newDriver(t)
  668. defer cleanup(d)
  669. if err := d.Create("1", ""); err != nil {
  670. t.Fatal(err)
  671. }
  672. mounted, err := Mounted(path.Join(d.home, "mnt", "1"))
  673. if err != nil {
  674. t.Fatal(err)
  675. }
  676. if mounted {
  677. t.Fatal("Id 1 should not be mounted")
  678. }
  679. }
  680. func TestMounted(t *testing.T) {
  681. t.Skip("FIXME: not a unit test")
  682. d := newDriver(t)
  683. defer cleanup(d)
  684. if err := d.Create("1", ""); err != nil {
  685. t.Fatal(err)
  686. }
  687. if _, err := d.Get("1"); err != nil {
  688. t.Fatal(err)
  689. }
  690. mounted, err := Mounted(path.Join(d.home, "mnt", "1"))
  691. if err != nil {
  692. t.Fatal(err)
  693. }
  694. if !mounted {
  695. t.Fatal("Id 1 should be mounted")
  696. }
  697. }
  698. func TestInitCleanedDriver(t *testing.T) {
  699. t.Skip("FIXME: not a unit test")
  700. d := newDriver(t)
  701. if err := d.Create("1", ""); err != nil {
  702. t.Fatal(err)
  703. }
  704. if _, err := d.Get("1"); err != nil {
  705. t.Fatal(err)
  706. }
  707. if err := d.Cleanup(); err != nil {
  708. t.Fatal(err)
  709. }
  710. driver, err := Init(d.home)
  711. if err != nil {
  712. t.Fatal(err)
  713. }
  714. d = driver.(*Driver)
  715. defer cleanup(d)
  716. if _, err := d.Get("1"); err != nil {
  717. t.Fatal(err)
  718. }
  719. }
  720. func TestMountMountedDriver(t *testing.T) {
  721. t.Skip("FIXME: not a unit test")
  722. d := newDriver(t)
  723. defer cleanup(d)
  724. if err := d.Create("1", ""); err != nil {
  725. t.Fatal(err)
  726. }
  727. // Perform get on same id to ensure that it will
  728. // not be mounted twice
  729. if _, err := d.Get("1"); err != nil {
  730. t.Fatal(err)
  731. }
  732. if _, err := d.Get("1"); err != nil {
  733. t.Fatal(err)
  734. }
  735. }
  736. func TestGetReturnsValidDevice(t *testing.T) {
  737. t.Skip("FIXME: not a unit test")
  738. d := newDriver(t)
  739. defer cleanup(d)
  740. if err := d.Create("1", ""); err != nil {
  741. t.Fatal(err)
  742. }
  743. if !d.HasDevice("1") {
  744. t.Fatalf("Expected id 1 to be in device set")
  745. }
  746. if _, err := d.Get("1"); err != nil {
  747. t.Fatal(err)
  748. }
  749. if !d.HasActivatedDevice("1") {
  750. t.Fatalf("Expected id 1 to be activated")
  751. }
  752. if !d.HasInitializedDevice("1") {
  753. t.Fatalf("Expected id 1 to be initialized")
  754. }
  755. }
  756. func TestDriverGetSize(t *testing.T) {
  757. t.Skip("FIXME: not a unit test")
  758. t.Skipf("Size is currently not implemented")
  759. d := newDriver(t)
  760. defer cleanup(d)
  761. if err := d.Create("1", ""); err != nil {
  762. t.Fatal(err)
  763. }
  764. mountPoint, err := d.Get("1")
  765. if err != nil {
  766. t.Fatal(err)
  767. }
  768. size := int64(1024)
  769. f, err := osCreate(path.Join(mountPoint, "test_file"))
  770. if err != nil {
  771. t.Fatal(err)
  772. }
  773. if err := f.Truncate(size); err != nil {
  774. t.Fatal(err)
  775. }
  776. f.Close()
  777. // diffSize, err := d.DiffSize("1")
  778. // if err != nil {
  779. // t.Fatal(err)
  780. // }
  781. // if diffSize != size {
  782. // t.Fatalf("Expected size %d got %d", size, diffSize)
  783. // }
  784. }
  785. func assertMap(t *testing.T, m map[string]bool, keys ...string) {
  786. for _, key := range keys {
  787. if _, exists := m[key]; !exists {
  788. t.Fatalf("Key not set: %s", key)
  789. }
  790. delete(m, key)
  791. }
  792. if len(m) != 0 {
  793. t.Fatalf("Unexpected keys: %v", m)
  794. }
  795. }