a scripting task - run commands, check output Tempting to use a scripting language to implement unit tests Engine integration tests are written in Go, as unit tests for an i n t e g r a t i o n - c l i package Much easier for contributors to write tests for their PRs when there isn't a separate language involved! Can reuse existing components for tests when it makes sense
( s * D o c k e r S u i t e ) T e s t K i l l C o n t a i n e r ( c * c h e c k . C ) { t e s t R e q u i r e s ( c , D a e m o n I s L i n u x ) o u t , _ : = d o c k e r C m d ( c , " r u n " , " - d " , " b u s y b o x " , " t o p " ) c l e a n e d C o n t a i n e r I D : = s t r i n g s . T r i m S p a c e ( o u t ) c . A s s e r t ( w a i t R u n ( c l e a n e d C o n t a i n e r I D ) , c h e c k . I s N i l ) d o c k e r C m d ( c , " k i l l " , c l e a n e d C o n t a i n e r I D ) o u t , _ = d o c k e r C m d ( c , " p s " , " - q " ) c . A s s e r t ( o u t , c h e c k e r . N o t ( c h e c k e r . C o n t a i n s ) , c l e a n e d C o n t a i n e r I D , c h e c k . C o m m e n t f ( " k i l l e d c o n t a i n e r i s s t i l l r u n n i n g " ) ) }
( s * D o c k e r S u i t e ) T e s t V o l u m e s A p i C r e a t e ( c * c h e c k . C ) { c o n f i g : = t y p e s . V o l u m e C r e a t e R e q u e s t { N a m e : " t e s t " , } s t a t u s , b , e r r : = s o c k R e q u e s t ( " P O S T " , " / v o l u m e s / c r e a t e " , c o n f i g ) c . A s s e r t ( e r r , c h e c k . I s N i l ) c . A s s e r t ( s t a t u s , c h e c k . E q u a l s , h t t p . S t a t u s C r e a t e d , c h e c k . C o m m e n t f ( s t r i n g ( b ) ) ) v a r v o l t y p e s . V o l u m e e r r = j s o n . U n m a r s h a l ( b , & v o l ) c . A s s e r t ( e r r , c h e c k e r . I s N i l ) c . A s s e r t ( f i l e p a t h . B a s e ( f i l e p a t h . D i r ( v o l . M o u n t p o i n t ) ) , c h e c k e r . E q u a l s , c o n f i g . N a m e ) }
g o c h e c k The setup function for a suite starts up the Docker daemon and any dependencies for that suite (for example, D o c k e r R e g i s t r y S u i t e starts a local registry to test against) A teardown function runs after each test in the suite and cleans up after the test (very important) Tests can interact with either the HTTP API or the command line tool Many helper functions to simplify common tasks
in-tree integration tests, we also want to: Test compatiblity between component versions; i.e. Engine 1.X against Registry 2.Y Test more complex setups with additional dependencies (proxies, databases, etc.)
integration test runner that runs complex tests on top of Docker. g o l e m creates containers for the services involved in the test using Docker Compose Each testsuite run happens inside its own container, for isolation Caches container images to avoid rebuilding them as part of test execution Open source, written in Go First use case: run complex end-to-end tests between Docker Registry and various versions of Docker Engine Future use case: matrix testing, running whole Docker integration-cli suite under various configurations
e ] ] d i n d = t r u e i m a g e s = [ " n g i n x : 1 . 9 " , " g o l a n g : 1 . 4 " , " h e l l o - w o r l d : l a t e s t " , " d m c g o w a n / t o k e n - s e r v e r : s i m p l e " ] [ [ s u i t e . p r e t e s t ] ] c o m m a n d = " / b i n / s h . / i n s t a l l _ c e r t s . s h l o c a l r e g i s t r y " [ [ s u i t e . t e s t r u n n e r ] ] c o m m a n d = " b a t s - t . " f o r m a t = " t a p " e n v = [ " T E S T _ R E P O = h e l l o - w o r l d " , " T E S T _ T A G = l a t e s t " , " T E S T _ U S E R = t e s t u s e r " , " T E S T _ P A S S W O R D = p a s s p a s s w o r d " , " T E S T _ R E G I S T R Y = l o c a l r e g i s t r y " , " T E S T _ S K I P _ P U L L = t r u e " ] [ [ s u i t e . c u s t o m i m a g e ] ] t a g = " g o l e m - d i s t r i b u t i o n : l a t e s t " d e f a u l t = " r e g i s t r y : 2 . 2 . 1 " [ [ s u i t e . c u s t o m i m a g e ] ] t a g = " g o l e m - r e g i s t r y : l a t e s t " d e f a u l t = " r e g i s t r y : 0 . 9 . 1 " Each suite also includes a d o c k e r - c o m p o s e . y m l file to connect the containers.
on GitHub: https://github.com/docker/docker/tree/master/integration-cli gocheck: http://labix.org/gocheck Golem code on GitHub: https://github.com/docker/golem