driver_test.go 22 KB

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