runtime_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. package docker
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/dotcloud/docker/sysinit"
  6. "github.com/dotcloud/docker/utils"
  7. "io"
  8. "log"
  9. "net"
  10. "os"
  11. "path/filepath"
  12. "runtime"
  13. "strconv"
  14. "strings"
  15. "sync"
  16. "syscall"
  17. "testing"
  18. "time"
  19. )
  20. const (
  21. unitTestImageName = "docker-test-image"
  22. unitTestImageID = "83599e29c455eb719f77d799bc7c51521b9551972f5a850d7ad265bc1b5292f6" // 1.0
  23. unitTestImageIDShort = "83599e29c455"
  24. unitTestNetworkBridge = "testdockbr0"
  25. unitTestStoreBase = "/var/lib/docker/unit-tests"
  26. testDaemonAddr = "127.0.0.1:4270"
  27. testDaemonProto = "tcp"
  28. )
  29. var (
  30. globalRuntime *Runtime
  31. startFds int
  32. startGoroutines int
  33. )
  34. func nuke(runtime *Runtime) error {
  35. if nonuke := os.Getenv("NONUKE"); nonuke != "" {
  36. return nil
  37. }
  38. var wg sync.WaitGroup
  39. for _, container := range runtime.List() {
  40. wg.Add(1)
  41. go func(c *Container) {
  42. c.Kill()
  43. wg.Done()
  44. }(container)
  45. }
  46. wg.Wait()
  47. runtime.Close()
  48. os.Remove(filepath.Join(runtime.config.Root, "linkgraph.db"))
  49. return os.RemoveAll(runtime.config.Root)
  50. }
  51. func cleanup(runtime *Runtime) error {
  52. for _, container := range runtime.List() {
  53. container.Kill()
  54. runtime.Destroy(container)
  55. }
  56. images, err := runtime.graph.Map()
  57. if err != nil {
  58. return err
  59. }
  60. for _, image := range images {
  61. if image.ID != unitTestImageID {
  62. runtime.graph.Delete(image.ID)
  63. }
  64. }
  65. return nil
  66. }
  67. func layerArchive(tarfile string) (io.Reader, error) {
  68. // FIXME: need to close f somewhere
  69. f, err := os.Open(tarfile)
  70. if err != nil {
  71. return nil, err
  72. }
  73. return f, nil
  74. }
  75. func init() {
  76. os.Setenv("TEST", "1")
  77. // Hack to run sys init during unit testing
  78. if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
  79. sysinit.SysInit()
  80. return
  81. }
  82. if uid := syscall.Geteuid(); uid != 0 {
  83. log.Fatal("docker tests need to be run as root")
  84. }
  85. // Copy dockerinit into our current testing directory, if provided (so we can test a separate dockerinit binary)
  86. if dockerinit := os.Getenv("TEST_DOCKERINIT_PATH"); dockerinit != "" {
  87. src, err := os.Open(dockerinit)
  88. if err != nil {
  89. log.Fatalf("Unable to open TEST_DOCKERINIT_PATH: %s\n", err)
  90. }
  91. defer src.Close()
  92. dst, err := os.OpenFile(filepath.Join(filepath.Dir(utils.SelfPath()), "dockerinit"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0555)
  93. if err != nil {
  94. log.Fatalf("Unable to create dockerinit in test directory: %s\n", err)
  95. }
  96. defer dst.Close()
  97. if _, err := io.Copy(dst, src); err != nil {
  98. log.Fatalf("Unable to copy dockerinit to TEST_DOCKERINIT_PATH: %s\n", err)
  99. }
  100. dst.Close()
  101. src.Close()
  102. }
  103. // Setup the base runtime, which will be duplicated for each test.
  104. // (no tests are run directly in the base)
  105. setupBaseImage()
  106. // Create the "global runtime" with a long-running daemon for integration tests
  107. spawnGlobalDaemon()
  108. startFds, startGoroutines = utils.GetTotalUsedFds(), runtime.NumGoroutine()
  109. }
  110. func setupBaseImage() {
  111. config := &DaemonConfig{
  112. Root: unitTestStoreBase,
  113. AutoRestart: false,
  114. BridgeIface: unitTestNetworkBridge,
  115. }
  116. runtime, err := NewRuntimeFromDirectory(config)
  117. if err != nil {
  118. log.Fatalf("Unable to create a runtime for tests:", err)
  119. }
  120. // Create the "Server"
  121. srv := &Server{
  122. runtime: runtime,
  123. pullingPool: make(map[string]struct{}),
  124. pushingPool: make(map[string]struct{}),
  125. }
  126. // If the unit test is not found, try to download it.
  127. if img, err := runtime.repositories.LookupImage(unitTestImageName); err != nil || img.ID != unitTestImageID {
  128. // Retrieve the Image
  129. if err := srv.ImagePull(unitTestImageName, "", os.Stdout, utils.NewStreamFormatter(false), nil, nil, true); err != nil {
  130. log.Fatalf("Unable to pull the test image:", err)
  131. }
  132. }
  133. }
  134. func spawnGlobalDaemon() {
  135. if globalRuntime != nil {
  136. utils.Debugf("Global runtime already exists. Skipping.")
  137. return
  138. }
  139. globalRuntime = mkRuntime(log.New(os.Stderr, "", 0))
  140. srv := &Server{
  141. runtime: globalRuntime,
  142. pullingPool: make(map[string]struct{}),
  143. pushingPool: make(map[string]struct{}),
  144. }
  145. // Spawn a Daemon
  146. go func() {
  147. utils.Debugf("Spawning global daemon for integration tests")
  148. if err := ListenAndServe(testDaemonProto, testDaemonAddr, srv, os.Getenv("DEBUG") != ""); err != nil {
  149. log.Fatalf("Unable to spawn the test daemon:", err)
  150. }
  151. }()
  152. // Give some time to ListenAndServer to actually start
  153. // FIXME: use inmem transports instead of tcp
  154. time.Sleep(time.Second)
  155. }
  156. // FIXME: test that ImagePull(json=true) send correct json output
  157. func GetTestImage(runtime *Runtime) *Image {
  158. imgs, err := runtime.graph.Map()
  159. if err != nil {
  160. log.Fatalf("Unable to get the test image:", err)
  161. }
  162. for _, image := range imgs {
  163. if image.ID == unitTestImageID {
  164. return image
  165. }
  166. }
  167. log.Fatalf("Test image %v not found", unitTestImageID)
  168. return nil
  169. }
  170. func TestRuntimeCreate(t *testing.T) {
  171. runtime := mkRuntime(t)
  172. defer nuke(runtime)
  173. // Make sure we start we 0 containers
  174. if len(runtime.List()) != 0 {
  175. t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
  176. }
  177. container, _, err := runtime.Create(&Config{
  178. Image: GetTestImage(runtime).ID,
  179. Cmd: []string{"ls", "-al"},
  180. },
  181. "",
  182. )
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. defer func() {
  187. if err := runtime.Destroy(container); err != nil {
  188. t.Error(err)
  189. }
  190. }()
  191. // Make sure we can find the newly created container with List()
  192. if len(runtime.List()) != 1 {
  193. t.Errorf("Expected 1 container, %v found", len(runtime.List()))
  194. }
  195. // Make sure the container List() returns is the right one
  196. if runtime.List()[0].ID != container.ID {
  197. t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
  198. }
  199. // Make sure we can get the container with Get()
  200. if runtime.Get(container.ID) == nil {
  201. t.Errorf("Unable to get newly created container")
  202. }
  203. // Make sure it is the right container
  204. if runtime.Get(container.ID) != container {
  205. t.Errorf("Get() returned the wrong container")
  206. }
  207. // Make sure Exists returns it as existing
  208. if !runtime.Exists(container.ID) {
  209. t.Errorf("Exists() returned false for a newly created container")
  210. }
  211. // Make sure create with bad parameters returns an error
  212. if _, _, err = runtime.Create(&Config{Image: GetTestImage(runtime).ID}, ""); err == nil {
  213. t.Fatal("Builder.Create should throw an error when Cmd is missing")
  214. }
  215. if _, _, err := runtime.Create(
  216. &Config{
  217. Image: GetTestImage(runtime).ID,
  218. Cmd: []string{},
  219. },
  220. "",
  221. ); err == nil {
  222. t.Fatal("Builder.Create should throw an error when Cmd is empty")
  223. }
  224. config := &Config{
  225. Image: GetTestImage(runtime).ID,
  226. Cmd: []string{"/bin/ls"},
  227. PortSpecs: []string{"80"},
  228. }
  229. container, _, err = runtime.Create(config, "")
  230. _, err = runtime.Commit(container, "testrepo", "testtag", "", "", config)
  231. if err != nil {
  232. t.Error(err)
  233. }
  234. // test expose 80:8000
  235. container, warnings, err := runtime.Create(&Config{
  236. Image: GetTestImage(runtime).ID,
  237. Cmd: []string{"ls", "-al"},
  238. PortSpecs: []string{"80:8000"},
  239. },
  240. "",
  241. )
  242. if err != nil {
  243. t.Fatal(err)
  244. }
  245. if warnings == nil || len(warnings) != 1 {
  246. t.Error("Expected a warning, got none")
  247. }
  248. }
  249. func TestDestroy(t *testing.T) {
  250. runtime := mkRuntime(t)
  251. defer nuke(runtime)
  252. container, _, err := runtime.Create(&Config{
  253. Image: GetTestImage(runtime).ID,
  254. Cmd: []string{"ls", "-al"},
  255. }, "")
  256. if err != nil {
  257. t.Fatal(err)
  258. }
  259. // Destroy
  260. if err := runtime.Destroy(container); err != nil {
  261. t.Error(err)
  262. }
  263. // Make sure runtime.Exists() behaves correctly
  264. if runtime.Exists("test_destroy") {
  265. t.Errorf("Exists() returned true")
  266. }
  267. // Make sure runtime.List() doesn't list the destroyed container
  268. if len(runtime.List()) != 0 {
  269. t.Errorf("Expected 0 container, %v found", len(runtime.List()))
  270. }
  271. // Make sure runtime.Get() refuses to return the unexisting container
  272. if runtime.Get(container.ID) != nil {
  273. t.Errorf("Unable to get newly created container")
  274. }
  275. // Make sure the container root directory does not exist anymore
  276. _, err = os.Stat(container.root)
  277. if err == nil || !os.IsNotExist(err) {
  278. t.Errorf("Container root directory still exists after destroy")
  279. }
  280. // Test double destroy
  281. if err := runtime.Destroy(container); err == nil {
  282. // It should have failed
  283. t.Errorf("Double destroy did not fail")
  284. }
  285. }
  286. func TestGet(t *testing.T) {
  287. runtime := mkRuntime(t)
  288. defer nuke(runtime)
  289. container1, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
  290. defer runtime.Destroy(container1)
  291. container2, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
  292. defer runtime.Destroy(container2)
  293. container3, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
  294. defer runtime.Destroy(container3)
  295. if runtime.Get(container1.ID) != container1 {
  296. t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.ID), container1)
  297. }
  298. if runtime.Get(container2.ID) != container2 {
  299. t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.ID), container2)
  300. }
  301. if runtime.Get(container3.ID) != container3 {
  302. t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.ID), container3)
  303. }
  304. }
  305. func startEchoServerContainer(t *testing.T, proto string) (*Runtime, *Container, string) {
  306. var (
  307. err error
  308. container *Container
  309. strPort string
  310. runtime = mkRuntime(t)
  311. port = 5554
  312. p Port
  313. )
  314. for {
  315. port += 1
  316. strPort = strconv.Itoa(port)
  317. var cmd string
  318. if proto == "tcp" {
  319. cmd = "socat TCP-LISTEN:" + strPort + ",reuseaddr,fork EXEC:/bin/cat"
  320. } else if proto == "udp" {
  321. cmd = "socat UDP-RECVFROM:" + strPort + ",fork EXEC:/bin/cat"
  322. } else {
  323. t.Fatal(fmt.Errorf("Unknown protocol %v", proto))
  324. }
  325. ep := make(map[Port]struct{}, 1)
  326. p = Port(fmt.Sprintf("%s/%s", strPort, proto))
  327. ep[p] = struct{}{}
  328. container, _, err = runtime.Create(&Config{
  329. Image: GetTestImage(runtime).ID,
  330. Cmd: []string{"sh", "-c", cmd},
  331. PortSpecs: []string{fmt.Sprintf("%s/%s", strPort, proto)},
  332. ExposedPorts: ep,
  333. }, "")
  334. if err != nil {
  335. nuke(runtime)
  336. t.Fatal(err)
  337. }
  338. if container != nil {
  339. break
  340. }
  341. t.Logf("Port %v already in use, trying another one", strPort)
  342. }
  343. container.hostConfig = &HostConfig{
  344. PortBindings: make(map[Port][]PortBinding),
  345. }
  346. container.hostConfig.PortBindings[p] = []PortBinding{
  347. {},
  348. }
  349. if err := container.Start(); err != nil {
  350. nuke(runtime)
  351. t.Fatal(err)
  352. }
  353. setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() {
  354. for !container.State.Running {
  355. time.Sleep(10 * time.Millisecond)
  356. }
  357. })
  358. // Even if the state is running, lets give some time to lxc to spawn the process
  359. container.WaitTimeout(500 * time.Millisecond)
  360. strPort = container.NetworkSettings.Ports[p][0].HostPort
  361. return runtime, container, strPort
  362. }
  363. // Run a container with a TCP port allocated, and test that it can receive connections on localhost
  364. func TestAllocateTCPPortLocalhost(t *testing.T) {
  365. runtime, container, port := startEchoServerContainer(t, "tcp")
  366. defer nuke(runtime)
  367. defer container.Kill()
  368. for i := 0; i != 10; i++ {
  369. conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%v", port))
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. defer conn.Close()
  374. input := bytes.NewBufferString("well hello there\n")
  375. _, err = conn.Write(input.Bytes())
  376. if err != nil {
  377. t.Fatal(err)
  378. }
  379. buf := make([]byte, 16)
  380. read := 0
  381. conn.SetReadDeadline(time.Now().Add(3 * time.Second))
  382. read, err = conn.Read(buf)
  383. if err != nil {
  384. if err, ok := err.(*net.OpError); ok {
  385. if err.Err == syscall.ECONNRESET {
  386. t.Logf("Connection reset by the proxy, socat is probably not listening yet, trying again in a sec")
  387. conn.Close()
  388. time.Sleep(time.Second)
  389. continue
  390. }
  391. if err.Timeout() {
  392. t.Log("Timeout, trying again")
  393. conn.Close()
  394. continue
  395. }
  396. }
  397. t.Fatal(err)
  398. }
  399. output := string(buf[:read])
  400. if !strings.Contains(output, "well hello there") {
  401. t.Fatal(fmt.Errorf("[%v] doesn't contain [well hello there]", output))
  402. } else {
  403. return
  404. }
  405. }
  406. t.Fatal("No reply from the container")
  407. }
  408. // Run a container with an UDP port allocated, and test that it can receive connections on localhost
  409. func TestAllocateUDPPortLocalhost(t *testing.T) {
  410. runtime, container, port := startEchoServerContainer(t, "udp")
  411. defer nuke(runtime)
  412. defer container.Kill()
  413. conn, err := net.Dial("udp", fmt.Sprintf("localhost:%v", port))
  414. if err != nil {
  415. t.Fatal(err)
  416. }
  417. defer conn.Close()
  418. input := bytes.NewBufferString("well hello there\n")
  419. buf := make([]byte, 16)
  420. // Try for a minute, for some reason the select in socat may take ages
  421. // to return even though everything on the path seems fine (i.e: the
  422. // UDPProxy forwards the traffic correctly and you can see the packets
  423. // on the interface from within the container).
  424. for i := 0; i != 120; i++ {
  425. _, err := conn.Write(input.Bytes())
  426. if err != nil {
  427. t.Fatal(err)
  428. }
  429. conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
  430. read, err := conn.Read(buf)
  431. if err == nil {
  432. output := string(buf[:read])
  433. if strings.Contains(output, "well hello there") {
  434. return
  435. }
  436. }
  437. }
  438. t.Fatal("No reply from the container")
  439. }
  440. func TestRestore(t *testing.T) {
  441. runtime1 := mkRuntime(t)
  442. defer nuke(runtime1)
  443. // Create a container with one instance of docker
  444. container1, _ := mkContainer(runtime1, []string{"_", "ls", "-al"}, t)
  445. defer runtime1.Destroy(container1)
  446. // Create a second container meant to be killed
  447. container2, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/cat"}, t)
  448. defer runtime1.Destroy(container2)
  449. // Start the container non blocking
  450. if err := container2.Start(); err != nil {
  451. t.Fatal(err)
  452. }
  453. if !container2.State.Running {
  454. t.Fatalf("Container %v should appear as running but isn't", container2.ID)
  455. }
  456. // Simulate a crash/manual quit of dockerd: process dies, states stays 'Running'
  457. cStdin, _ := container2.StdinPipe()
  458. cStdin.Close()
  459. if err := container2.WaitTimeout(2 * time.Second); err != nil {
  460. t.Fatal(err)
  461. }
  462. container2.State.Running = true
  463. container2.ToDisk()
  464. if len(runtime1.List()) != 2 {
  465. t.Errorf("Expected 2 container, %v found", len(runtime1.List()))
  466. }
  467. if err := container1.Run(); err != nil {
  468. t.Fatal(err)
  469. }
  470. if !container2.State.Running {
  471. t.Fatalf("Container %v should appear as running but isn't", container2.ID)
  472. }
  473. // Here are are simulating a docker restart - that is, reloading all containers
  474. // from scratch
  475. runtime1.config.AutoRestart = false
  476. runtime2, err := NewRuntimeFromDirectory(runtime1.config)
  477. if err != nil {
  478. t.Fatal(err)
  479. }
  480. defer nuke(runtime2)
  481. if len(runtime2.List()) != 2 {
  482. t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
  483. }
  484. runningCount := 0
  485. for _, c := range runtime2.List() {
  486. if c.State.Running {
  487. t.Errorf("Running container found: %v (%v)", c.ID, c.Path)
  488. runningCount++
  489. }
  490. }
  491. if runningCount != 0 {
  492. t.Fatalf("Expected 0 container alive, %d found", runningCount)
  493. }
  494. container3 := runtime2.Get(container1.ID)
  495. if container3 == nil {
  496. t.Fatal("Unable to Get container")
  497. }
  498. if err := container3.Run(); err != nil {
  499. t.Fatal(err)
  500. }
  501. container2.State.Running = false
  502. }
  503. func TestReloadContainerLinks(t *testing.T) {
  504. runtime1 := mkRuntime(t)
  505. defer nuke(runtime1)
  506. // Create a container with one instance of docker
  507. container1, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/sh"}, t)
  508. defer runtime1.Destroy(container1)
  509. // Create a second container meant to be killed
  510. container2, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/cat"}, t)
  511. defer runtime1.Destroy(container2)
  512. // Start the container non blocking
  513. if err := container2.Start(); err != nil {
  514. t.Fatal(err)
  515. }
  516. // Add a link to container 2
  517. container1.hostConfig.Links = []string{"/" + container2.ID + ":first"}
  518. if err := runtime1.RegisterLink(container1, container2, "first"); err != nil {
  519. t.Fatal(err)
  520. }
  521. if err := container1.Start(); err != nil {
  522. t.Fatal(err)
  523. }
  524. if !container2.State.Running {
  525. t.Fatalf("Container %v should appear as running but isn't", container2.ID)
  526. }
  527. if !container1.State.Running {
  528. t.Fatalf("Container %s should appear as running but isn't", container1.ID)
  529. }
  530. if len(runtime1.List()) != 2 {
  531. t.Errorf("Expected 2 container, %v found", len(runtime1.List()))
  532. }
  533. // Here are are simulating a docker restart - that is, reloading all containers
  534. // from scratch
  535. runtime1.config.AutoRestart = true
  536. runtime2, err := NewRuntimeFromDirectory(runtime1.config)
  537. if err != nil {
  538. t.Fatal(err)
  539. }
  540. defer nuke(runtime2)
  541. if len(runtime2.List()) != 2 {
  542. t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
  543. }
  544. runningCount := 0
  545. for _, c := range runtime2.List() {
  546. if c.State.Running {
  547. runningCount++
  548. }
  549. }
  550. if runningCount != 2 {
  551. t.Fatalf("Expected 2 container alive, %d found", runningCount)
  552. }
  553. // Make sure container 2 ( the child of container 1 ) was registered and started first
  554. // with the runtime
  555. first := runtime2.containers.Front()
  556. if first.Value.(*Container).ID != container2.ID {
  557. t.Fatalf("Container 2 %s should be registered first in the runtime", container2.ID)
  558. }
  559. // Verify that the link is still registered in the runtime
  560. entity := runtime2.containerGraph.Get(container1.Name)
  561. if entity == nil {
  562. t.Fatal("Entity should not be nil")
  563. }
  564. }
  565. func TestDefaultContainerName(t *testing.T) {
  566. runtime := mkRuntime(t)
  567. defer nuke(runtime)
  568. srv := &Server{runtime: runtime}
  569. config, _, _, err := ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  570. if err != nil {
  571. t.Fatal(err)
  572. }
  573. shortId, _, err := srv.ContainerCreate(config, "some_name")
  574. if err != nil {
  575. t.Fatal(err)
  576. }
  577. container := runtime.Get(shortId)
  578. containerID := container.ID
  579. if container.Name != "/some_name" {
  580. t.Fatalf("Expect /some_name got %s", container.Name)
  581. }
  582. paths := runtime.containerGraph.RefPaths(containerID)
  583. if paths == nil || len(paths) == 0 {
  584. t.Fatalf("Could not find edges for %s", containerID)
  585. }
  586. edge := paths[0]
  587. if edge.ParentID != "0" {
  588. t.Fatalf("Expected engine got %s", edge.ParentID)
  589. }
  590. if edge.EntityID != containerID {
  591. t.Fatalf("Expected %s got %s", containerID, edge.EntityID)
  592. }
  593. if edge.Name != "some_name" {
  594. t.Fatalf("Expected some_name got %s", edge.Name)
  595. }
  596. }
  597. func TestRandomContainerName(t *testing.T) {
  598. runtime := mkRuntime(t)
  599. defer nuke(runtime)
  600. srv := &Server{runtime: runtime}
  601. config, _, _, err := ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  602. if err != nil {
  603. t.Fatal(err)
  604. }
  605. shortId, _, err := srv.ContainerCreate(config, "")
  606. if err != nil {
  607. t.Fatal(err)
  608. }
  609. container := runtime.Get(shortId)
  610. containerID := container.ID
  611. if container.Name == "" {
  612. t.Fatalf("Expected not empty container name")
  613. }
  614. paths := runtime.containerGraph.RefPaths(containerID)
  615. if paths == nil || len(paths) == 0 {
  616. t.Fatalf("Could not find edges for %s", containerID)
  617. }
  618. edge := paths[0]
  619. if edge.ParentID != "0" {
  620. t.Fatalf("Expected engine got %s", edge.ParentID)
  621. }
  622. if edge.EntityID != containerID {
  623. t.Fatalf("Expected %s got %s", containerID, edge.EntityID)
  624. }
  625. if edge.Name == "" {
  626. t.Fatalf("Expected not empty container name")
  627. }
  628. }
  629. func TestLinkChildContainer(t *testing.T) {
  630. runtime := mkRuntime(t)
  631. defer nuke(runtime)
  632. srv := &Server{runtime: runtime}
  633. config, _, _, err := ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  634. if err != nil {
  635. t.Fatal(err)
  636. }
  637. shortId, _, err := srv.ContainerCreate(config, "/webapp")
  638. if err != nil {
  639. t.Fatal(err)
  640. }
  641. container := runtime.Get(shortId)
  642. webapp, err := runtime.GetByName("/webapp")
  643. if err != nil {
  644. t.Fatal(err)
  645. }
  646. if webapp.ID != container.ID {
  647. t.Fatalf("Expect webapp id to match container id: %s != %s", webapp.ID, container.ID)
  648. }
  649. config, _, _, err = ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  650. if err != nil {
  651. t.Fatal(err)
  652. }
  653. shortId, _, err = srv.ContainerCreate(config, "")
  654. if err != nil {
  655. t.Fatal(err)
  656. }
  657. childContainer := runtime.Get(shortId)
  658. if err := runtime.RegisterLink(webapp, childContainer, "db"); err != nil {
  659. t.Fatal(err)
  660. }
  661. // Get the child by it's new name
  662. db, err := runtime.GetByName("/webapp/db")
  663. if err != nil {
  664. t.Fatal(err)
  665. }
  666. if db.ID != childContainer.ID {
  667. t.Fatalf("Expect db id to match container id: %s != %s", db.ID, childContainer.ID)
  668. }
  669. }
  670. func TestGetAllChildren(t *testing.T) {
  671. runtime := mkRuntime(t)
  672. defer nuke(runtime)
  673. srv := &Server{runtime: runtime}
  674. config, _, _, err := ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  675. if err != nil {
  676. t.Fatal(err)
  677. }
  678. shortId, _, err := srv.ContainerCreate(config, "/webapp")
  679. if err != nil {
  680. t.Fatal(err)
  681. }
  682. container := runtime.Get(shortId)
  683. webapp, err := runtime.GetByName("/webapp")
  684. if err != nil {
  685. t.Fatal(err)
  686. }
  687. if webapp.ID != container.ID {
  688. t.Fatalf("Expect webapp id to match container id: %s != %s", webapp.ID, container.ID)
  689. }
  690. config, _, _, err = ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
  691. if err != nil {
  692. t.Fatal(err)
  693. }
  694. shortId, _, err = srv.ContainerCreate(config, "")
  695. if err != nil {
  696. t.Fatal(err)
  697. }
  698. childContainer := runtime.Get(shortId)
  699. if err := runtime.RegisterLink(webapp, childContainer, "db"); err != nil {
  700. t.Fatal(err)
  701. }
  702. children, err := runtime.Children("/webapp")
  703. if err != nil {
  704. t.Fatal(err)
  705. }
  706. if children == nil {
  707. t.Fatal("Children should not be nil")
  708. }
  709. if len(children) == 0 {
  710. t.Fatal("Children should not be empty")
  711. }
  712. for key, value := range children {
  713. if key != "/webapp/db" {
  714. t.Fatalf("Expected /webapp/db got %s", key)
  715. }
  716. if value.ID != childContainer.ID {
  717. t.Fatalf("Expected id %s got %s", childContainer.ID, value.ID)
  718. }
  719. }
  720. }
  721. func TestGetFullName(t *testing.T) {
  722. runtime := mkRuntime(t)
  723. defer nuke(runtime)
  724. name, err := runtime.getFullName("testing")
  725. if err != nil {
  726. t.Fatal(err)
  727. }
  728. if name != "/testing" {
  729. t.Fatalf("Expected /testing got %s", name)
  730. }
  731. if _, err := runtime.getFullName(""); err == nil {
  732. t.Fatal("Error should not be nil")
  733. }
  734. }