2014-09-09 04:33:17 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-09-09 04:33:17 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package dockertools
import (
2015-05-08 17:53:00 +00:00
"encoding/json"
2014-09-09 04:33:17 +00:00
"fmt"
"hash/adler32"
"reflect"
2015-04-13 22:25:14 +00:00
"sort"
2015-06-05 00:37:07 +00:00
"strings"
2014-09-09 04:33:17 +00:00
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2015-04-02 20:14:52 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
2014-11-15 13:50:59 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
2015-04-13 22:25:14 +00:00
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
2015-04-28 18:02:29 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/network"
2015-01-14 23:22:21 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
2015-01-05 23:24:49 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
2015-06-05 00:37:07 +00:00
"github.com/docker/docker/pkg/jsonmessage"
2014-11-15 13:50:59 +00:00
docker "github.com/fsouza/go-dockerclient"
2014-09-09 04:33:17 +00:00
)
func verifyCalls ( t * testing . T , fakeDocker * FakeDockerClient , calls [ ] string ) {
fakeDocker . Lock ( )
defer fakeDocker . Unlock ( )
verifyStringArrayEquals ( t , fakeDocker . called , calls )
}
func verifyStringArrayEquals ( t * testing . T , actual , expected [ ] string ) {
invalid := len ( actual ) != len ( expected )
if ! invalid {
for ix , value := range actual {
if expected [ ix ] != value {
invalid = true
}
}
}
if invalid {
t . Errorf ( "Expected: %#v, Actual: %#v" , expected , actual )
}
}
func TestGetContainerID ( t * testing . T ) {
fakeDocker := & FakeDockerClient { }
fakeDocker . ContainerList = [ ] docker . APIContainers {
{
ID : "foobar" ,
2015-02-26 20:27:14 +00:00
Names : [ ] string { "/k8s_foo_qux_ns_1234_42" } ,
2014-09-09 04:33:17 +00:00
} ,
{
ID : "barbar" ,
2015-02-26 20:27:14 +00:00
Names : [ ] string { "/k8s_bar_qux_ns_2565_42" } ,
2014-09-09 04:33:17 +00:00
} ,
}
fakeDocker . Container = & docker . Container {
ID : "foobar" ,
}
2014-09-29 21:38:31 +00:00
dockerContainers , err := GetKubeletDockerContainers ( fakeDocker , false )
2014-09-09 04:33:17 +00:00
if err != nil {
t . Errorf ( "Expected no error, Got %#v" , err )
}
if len ( dockerContainers ) != 2 {
t . Errorf ( "Expected %#v, Got %#v" , fakeDocker . ContainerList , dockerContainers )
}
verifyCalls ( t , fakeDocker , [ ] string { "list" } )
2015-02-26 20:27:14 +00:00
dockerContainer , found , _ := dockerContainers . FindPodContainer ( "qux_ns" , "" , "foo" )
2014-09-09 04:33:17 +00:00
if dockerContainer == nil || ! found {
t . Errorf ( "Failed to find container %#v" , dockerContainer )
}
2014-12-17 05:11:27 +00:00
fakeDocker . ClearCalls ( )
2014-09-09 04:33:17 +00:00
dockerContainer , found , _ = dockerContainers . FindPodContainer ( "foobar" , "" , "foo" )
verifyCalls ( t , fakeDocker , [ ] string { } )
if dockerContainer != nil || found {
t . Errorf ( "Should not have found container %#v" , dockerContainer )
}
}
2015-01-05 01:30:30 +00:00
func verifyPackUnpack ( t * testing . T , podNamespace , podUID , podName , containerName string ) {
2014-09-09 04:33:17 +00:00
container := & api . Container { Name : containerName }
hasher := adler32 . New ( )
2015-01-05 23:24:49 +00:00
util . DeepHashObject ( hasher , * container )
2014-09-09 04:33:17 +00:00
computedHash := uint64 ( hasher . Sum32 ( ) )
2015-02-26 20:27:14 +00:00
podFullName := fmt . Sprintf ( "%s_%s" , podName , podNamespace )
2015-03-20 11:55:02 +00:00
name := BuildDockerName ( KubeletContainerName { podFullName , types . UID ( podUID ) , container . Name } , container )
returned , hash , err := ParseDockerName ( name )
2015-03-12 23:31:57 +00:00
if err != nil {
t . Errorf ( "Failed to parse Docker container name %q: %v" , name , err )
}
2015-03-20 11:55:02 +00:00
if podFullName != returned . PodFullName || podUID != string ( returned . PodUID ) || containerName != returned . ContainerName || computedHash != hash {
t . Errorf ( "For (%s, %s, %s, %d), unpacked (%s, %s, %s, %d)" , podFullName , podUID , containerName , computedHash , returned . PodFullName , returned . PodUID , returned . ContainerName , hash )
2014-09-09 04:33:17 +00:00
}
}
2015-06-15 19:04:30 +00:00
func TestContainerNaming ( t * testing . T ) {
2015-01-10 01:19:31 +00:00
podUID := "12345678"
verifyPackUnpack ( t , "file" , podUID , "name" , "container" )
verifyPackUnpack ( t , "file" , podUID , "name-with-dashes" , "container" )
2015-01-05 01:30:30 +00:00
// UID is same as pod name
2015-01-10 01:19:31 +00:00
verifyPackUnpack ( t , "file" , podUID , podUID , "container" )
2014-09-25 00:05:53 +00:00
// No Container name
2015-01-10 01:19:31 +00:00
verifyPackUnpack ( t , "other" , podUID , "name" , "" )
2014-09-09 04:33:17 +00:00
container := & api . Container { Name : "container" }
podName := "foo"
podNamespace := "test"
2015-02-26 20:27:14 +00:00
name := fmt . Sprintf ( "k8s_%s_%s_%s_%s_42" , container . Name , podName , podNamespace , podUID )
podFullName := fmt . Sprintf ( "%s_%s" , podName , podNamespace )
2015-01-10 01:19:31 +00:00
2015-03-20 11:55:02 +00:00
returned , hash , err := ParseDockerName ( name )
2015-03-12 23:31:57 +00:00
if err != nil {
t . Errorf ( "Failed to parse Docker container name %q: %v" , name , err )
}
2015-03-20 11:55:02 +00:00
if returned . PodFullName != podFullName || string ( returned . PodUID ) != podUID || returned . ContainerName != container . Name || hash != 0 {
t . Errorf ( "unexpected parse: %s %s %s %d" , returned . PodFullName , returned . PodUID , returned . ContainerName , hash )
2014-09-09 04:33:17 +00:00
}
}
2015-04-21 20:02:50 +00:00
func TestVersion ( t * testing . T ) {
2015-04-20 17:48:18 +00:00
fakeDocker := & FakeDockerClient { VersionInfo : docker . Env { "Version=1.1.3" , "ApiVersion=1.15" } }
2015-04-21 20:02:50 +00:00
manager := & DockerManager { client : fakeDocker }
version , err := manager . Version ( )
2014-10-14 10:08:48 +00:00
if err != nil {
t . Errorf ( "got error while getting docker server version - %s" , err )
}
2015-04-20 17:48:18 +00:00
expectedVersion , _ := docker . NewAPIVersion ( "1.15" )
if e , a := expectedVersion . String ( ) , version . String ( ) ; e != a {
t . Errorf ( "invalid docker server version. expected: %v, got: %v" , e , a )
2014-10-14 10:08:48 +00:00
}
}
func TestExecSupportExists ( t * testing . T ) {
2015-04-20 17:48:18 +00:00
fakeDocker := & FakeDockerClient { VersionInfo : docker . Env { "Version=1.3.0" , "ApiVersion=1.15" } }
2015-04-22 17:20:05 +00:00
runner := & DockerManager { client : fakeDocker }
2014-10-14 10:08:48 +00:00
useNativeExec , err := runner . nativeExecSupportExists ( )
if err != nil {
t . Errorf ( "got error while checking for exec support - %s" , err )
}
if ! useNativeExec {
t . Errorf ( "invalid exec support check output. Expected true" )
}
}
func TestExecSupportNotExists ( t * testing . T ) {
2015-04-20 17:48:18 +00:00
fakeDocker := & FakeDockerClient { VersionInfo : docker . Env { "Version=1.1.2" , "ApiVersion=1.14" } }
2015-04-22 17:20:05 +00:00
runner := & DockerManager { client : fakeDocker }
2014-10-14 10:08:48 +00:00
useNativeExec , _ := runner . nativeExecSupportExists ( )
if useNativeExec {
t . Errorf ( "invalid exec support check output." )
}
}
2014-09-09 04:33:17 +00:00
func TestDockerContainerCommand ( t * testing . T ) {
2015-04-22 17:20:05 +00:00
runner := & DockerManager { }
2014-09-09 04:33:17 +00:00
containerID := "1234"
command := [ ] string { "ls" }
cmd , _ := runner . getRunInContainerCommand ( containerID , command )
if cmd . Dir != "/var/lib/docker/execdriver/native/" + containerID {
t . Errorf ( "unexpected command CWD: %s" , cmd . Dir )
}
if ! reflect . DeepEqual ( cmd . Args , [ ] string { "/usr/sbin/nsinit" , "exec" , "ls" } ) {
2015-01-18 07:32:34 +00:00
t . Errorf ( "unexpected command args: %s" , cmd . Args )
2014-09-09 04:33:17 +00:00
}
}
2015-03-17 00:51:20 +00:00
func TestParseImageName ( t * testing . T ) {
tests := [ ] struct {
imageName string
name string
tag string
} {
{ "ubuntu" , "ubuntu" , "" } ,
{ "ubuntu:2342" , "ubuntu" , "2342" } ,
{ "ubuntu:latest" , "ubuntu" , "latest" } ,
{ "foo/bar:445566" , "foo/bar" , "445566" } ,
{ "registry.example.com:5000/foobar" , "registry.example.com:5000/foobar" , "" } ,
{ "registry.example.com:5000/foobar:5342" , "registry.example.com:5000/foobar" , "5342" } ,
{ "registry.example.com:5000/foobar:latest" , "registry.example.com:5000/foobar" , "latest" } ,
}
for _ , test := range tests {
name , tag := parseImageName ( test . imageName )
if name != test . name || tag != test . tag {
t . Errorf ( "Expected name/tag: %s/%s, got %s/%s" , test . name , test . tag , name , tag )
}
}
2015-03-17 22:16:33 +00:00
}
2015-05-08 17:30:59 +00:00
func TestPullWithNoSecrets ( t * testing . T ) {
2015-03-17 00:51:20 +00:00
tests := [ ] struct {
imageName string
expectedImage string
} {
2015-05-08 17:30:59 +00:00
{ "ubuntu" , "ubuntu:latest using {}" } ,
{ "ubuntu:2342" , "ubuntu:2342 using {}" } ,
{ "ubuntu:latest" , "ubuntu:latest using {}" } ,
{ "foo/bar:445566" , "foo/bar:445566 using {}" } ,
{ "registry.example.com:5000/foobar" , "registry.example.com:5000/foobar:latest using {}" } ,
{ "registry.example.com:5000/foobar:5342" , "registry.example.com:5000/foobar:5342 using {}" } ,
{ "registry.example.com:5000/foobar:latest" , "registry.example.com:5000/foobar:latest using {}" } ,
2015-03-17 00:51:20 +00:00
}
for _ , test := range tests {
fakeKeyring := & credentialprovider . FakeKeyring { }
fakeClient := & FakeDockerClient { }
dp := dockerPuller {
client : fakeClient ,
keyring : fakeKeyring ,
}
2015-05-08 17:53:00 +00:00
err := dp . Pull ( test . imageName , [ ] api . Secret { } )
2015-03-17 00:51:20 +00:00
if err != nil {
t . Errorf ( "unexpected non-nil err: %s" , err )
continue
}
if e , a := 1 , len ( fakeClient . pulled ) ; e != a {
t . Errorf ( "%s: expected 1 pulled image, got %d: %v" , test . imageName , a , fakeClient . pulled )
continue
}
if e , a := test . expectedImage , fakeClient . pulled [ 0 ] ; e != a {
t . Errorf ( "%s: expected pull of %q, but got %q" , test . imageName , e , a )
2015-03-17 22:16:33 +00:00
}
}
}
2015-06-05 00:37:07 +00:00
func TestPullWithJSONError ( t * testing . T ) {
tests := map [ string ] struct {
imageName string
err error
expectedError string
} {
"Json error" : {
"ubuntu" ,
& jsonmessage . JSONError { Code : 50 , Message : "Json error" } ,
"Json error" ,
} ,
"Bad gateway" : {
"ubuntu" ,
& jsonmessage . JSONError { Code : 502 , Message : "<!doctype html>\n<html class=\"no-js\" lang=\"\">\n <head>\n </head>\n <body>\n <h1>Oops, there was an error!</h1>\n <p>We have been contacted of this error, feel free to check out <a href=\"http://status.docker.com/\">status.docker.com</a>\n to see if there is a bigger issue.</p>\n\n </body>\n</html>" } ,
"because the registry is temporarily unavailbe" ,
} ,
}
for i , test := range tests {
fakeKeyring := & credentialprovider . FakeKeyring { }
fakeClient := & FakeDockerClient {
Errors : map [ string ] error { "pull" : test . err } ,
}
puller := & dockerPuller {
client : fakeClient ,
keyring : fakeKeyring ,
}
err := puller . Pull ( test . imageName , [ ] api . Secret { } )
if err == nil || ! strings . Contains ( err . Error ( ) , test . expectedError ) {
t . Errorf ( "%d: expect error %s, got : %s" , i , test . expectedError , err )
continue
}
}
}
2015-05-08 17:53:00 +00:00
func TestPullWithSecrets ( t * testing . T ) {
2015-05-19 13:00:12 +00:00
// auth value is equivalent to: "username":"passed-user","password":"passed-password"
dockerCfg := map [ string ] map [ string ] string { "index.docker.io/v1/" : { "email" : "passed-email" , "auth" : "cGFzc2VkLXVzZXI6cGFzc2VkLXBhc3N3b3Jk" } }
2015-05-08 17:53:00 +00:00
dockercfgContent , err := json . Marshal ( dockerCfg )
if err != nil {
t . Errorf ( "unexpected error: %v" , err )
}
tests := map [ string ] struct {
imageName string
passedSecrets [ ] api . Secret
builtInDockerConfig credentialprovider . DockerConfig
expectedPulls [ ] string
} {
"no matching secrets" : {
"ubuntu" ,
[ ] api . Secret { } ,
credentialprovider . DockerConfig ( map [ string ] credentialprovider . DockerConfigEntry { } ) ,
[ ] string { "ubuntu:latest using {}" } ,
} ,
"default keyring secrets" : {
"ubuntu" ,
[ ] api . Secret { } ,
credentialprovider . DockerConfig ( map [ string ] credentialprovider . DockerConfigEntry { "index.docker.io/v1/" : { "built-in" , "password" , "email" } } ) ,
[ ] string { ` ubuntu:latest using { "username":"built-in","password":"password","email":"email"} ` } ,
} ,
"default keyring secrets unused" : {
"ubuntu" ,
[ ] api . Secret { } ,
credentialprovider . DockerConfig ( map [ string ] credentialprovider . DockerConfigEntry { "extraneous" : { "built-in" , "password" , "email" } } ) ,
[ ] string { ` ubuntu:latest using { } ` } ,
} ,
"builtin keyring secrets, but use passed" : {
"ubuntu" ,
[ ] api . Secret { { Type : api . SecretTypeDockercfg , Data : map [ string ] [ ] byte { api . DockerConfigKey : dockercfgContent } } } ,
credentialprovider . DockerConfig ( map [ string ] credentialprovider . DockerConfigEntry { "index.docker.io/v1/" : { "built-in" , "password" , "email" } } ) ,
[ ] string { ` ubuntu:latest using { "username":"passed-user","password":"passed-password","email":"passed-email"} ` } ,
} ,
}
for _ , test := range tests {
builtInKeyRing := & credentialprovider . BasicDockerKeyring { }
builtInKeyRing . Add ( test . builtInDockerConfig )
fakeClient := & FakeDockerClient { }
dp := dockerPuller {
client : fakeClient ,
keyring : builtInKeyRing ,
}
err := dp . Pull ( test . imageName , test . passedSecrets )
if err != nil {
t . Errorf ( "unexpected non-nil err: %s" , err )
continue
}
if e , a := 1 , len ( fakeClient . pulled ) ; e != a {
t . Errorf ( "%s: expected 1 pulled image, got %d: %v" , test . imageName , a , fakeClient . pulled )
continue
}
if e , a := test . expectedPulls , fakeClient . pulled ; ! reflect . DeepEqual ( e , a ) {
t . Errorf ( "%s: expected pull of %v, but got %v" , test . imageName , e , a )
}
}
}
2015-02-10 15:23:32 +00:00
func TestDockerKeyringLookupFails ( t * testing . T ) {
fakeKeyring := & credentialprovider . FakeKeyring { }
fakeClient := & FakeDockerClient {
2015-04-09 18:57:53 +00:00
Errors : map [ string ] error { "pull" : fmt . Errorf ( "test error" ) } ,
2015-02-10 15:23:32 +00:00
}
dp := dockerPuller {
client : fakeClient ,
keyring : fakeKeyring ,
}
2015-05-08 17:53:00 +00:00
err := dp . Pull ( "host/repository/image:version" , [ ] api . Secret { } )
2015-02-10 15:23:32 +00:00
if err == nil {
t . Errorf ( "unexpected non-error" )
}
2015-03-17 00:51:20 +00:00
msg := "image pull failed for host/repository/image:version, this may be because there are no credentials on this request. details: (test error)"
2015-02-10 15:23:32 +00:00
if err . Error ( ) != msg {
t . Errorf ( "expected: %s, saw: %s" , msg , err . Error ( ) )
}
}
2014-09-06 01:13:19 +00:00
func TestDockerKeyringLookup ( t * testing . T ) {
ada := docker . AuthConfiguration {
Username : "ada" ,
Password : "smash" ,
Email : "ada@example.com" ,
}
grace := docker . AuthConfiguration {
Username : "grace" ,
Password : "squash" ,
Email : "grace@example.com" ,
}
2014-11-15 13:50:59 +00:00
dk := & credentialprovider . BasicDockerKeyring { }
dk . Add ( credentialprovider . DockerConfig {
"bar.example.com/pong" : credentialprovider . DockerConfigEntry {
Username : grace . Username ,
Password : grace . Password ,
Email : grace . Email ,
} ,
"bar.example.com" : credentialprovider . DockerConfigEntry {
Username : ada . Username ,
Password : ada . Password ,
Email : ada . Email ,
} ,
} )
2014-09-06 01:13:19 +00:00
tests := [ ] struct {
image string
2015-05-08 17:30:59 +00:00
match [ ] docker . AuthConfiguration
2014-09-06 01:13:19 +00:00
ok bool
} {
// direct match
2015-05-08 17:30:59 +00:00
{ "bar.example.com" , [ ] docker . AuthConfiguration { ada } , true } ,
2014-09-06 01:13:19 +00:00
// direct match deeper than other possible matches
2015-05-08 17:30:59 +00:00
{ "bar.example.com/pong" , [ ] docker . AuthConfiguration { grace , ada } , true } ,
2014-09-06 01:13:19 +00:00
// no direct match, deeper path ignored
2015-05-08 17:30:59 +00:00
{ "bar.example.com/ping" , [ ] docker . AuthConfiguration { ada } , true } ,
2014-09-06 01:13:19 +00:00
// match first part of path token
2015-05-08 17:30:59 +00:00
{ "bar.example.com/pongz" , [ ] docker . AuthConfiguration { grace , ada } , true } ,
2014-09-06 01:13:19 +00:00
// match regardless of sub-path
2015-05-08 17:30:59 +00:00
{ "bar.example.com/pong/pang" , [ ] docker . AuthConfiguration { grace , ada } , true } ,
2014-09-06 01:13:19 +00:00
// no host match
2015-05-08 17:30:59 +00:00
{ "example.com" , [ ] docker . AuthConfiguration { } , false } ,
{ "foo.example.com" , [ ] docker . AuthConfiguration { } , false } ,
2014-09-06 01:13:19 +00:00
}
for i , tt := range tests {
2014-11-15 13:50:59 +00:00
match , ok := dk . Lookup ( tt . image )
2014-09-06 01:13:19 +00:00
if tt . ok != ok {
t . Errorf ( "case %d: expected ok=%t, got %t" , i , tt . ok , ok )
}
if ! reflect . DeepEqual ( tt . match , match ) {
t . Errorf ( "case %d: expected match=%#v, got %#v" , i , tt . match , match )
}
}
}
2014-12-10 20:33:38 +00:00
2015-01-26 22:06:12 +00:00
// This validates that dockercfg entries with a scheme and url path are properly matched
// by images that only match the hostname.
// NOTE: the above covers the case of a more specific match trumping just hostname.
func TestIssue3797 ( t * testing . T ) {
rex := docker . AuthConfiguration {
Username : "rex" ,
Password : "tiny arms" ,
Email : "rex@example.com" ,
}
dk := & credentialprovider . BasicDockerKeyring { }
dk . Add ( credentialprovider . DockerConfig {
"https://quay.io/v1/" : credentialprovider . DockerConfigEntry {
Username : rex . Username ,
Password : rex . Password ,
Email : rex . Email ,
} ,
} )
tests := [ ] struct {
image string
2015-05-08 17:30:59 +00:00
match [ ] docker . AuthConfiguration
2015-01-26 22:06:12 +00:00
ok bool
} {
// direct match
2015-05-08 17:30:59 +00:00
{ "quay.io" , [ ] docker . AuthConfiguration { rex } , true } ,
2015-01-26 22:06:12 +00:00
// partial matches
2015-05-08 17:30:59 +00:00
{ "quay.io/foo" , [ ] docker . AuthConfiguration { rex } , true } ,
{ "quay.io/foo/bar" , [ ] docker . AuthConfiguration { rex } , true } ,
2015-01-26 22:06:12 +00:00
}
for i , tt := range tests {
match , ok := dk . Lookup ( tt . image )
if tt . ok != ok {
t . Errorf ( "case %d: expected ok=%t, got %t" , i , tt . ok , ok )
}
if ! reflect . DeepEqual ( tt . match , match ) {
t . Errorf ( "case %d: expected match=%#v, got %#v" , i , tt . match , match )
}
}
}
2014-12-10 20:33:38 +00:00
type imageTrackingDockerClient struct {
* FakeDockerClient
imageName string
}
2014-12-13 01:43:07 +00:00
2014-12-10 20:33:38 +00:00
func ( f * imageTrackingDockerClient ) InspectImage ( name string ) ( image * docker . Image , err error ) {
image , err = f . FakeDockerClient . InspectImage ( name )
f . imageName = name
return
}
2014-12-13 01:43:07 +00:00
2014-12-10 20:33:38 +00:00
func TestIsImagePresent ( t * testing . T ) {
2014-12-13 01:43:07 +00:00
cl := & imageTrackingDockerClient { & FakeDockerClient { } , "" }
2014-12-10 20:33:38 +00:00
puller := & dockerPuller {
client : cl ,
}
_ , _ = puller . IsImagePresent ( "abc:123" )
if cl . imageName != "abc:123" {
t . Errorf ( "expected inspection of image abc:123, instead inspected image %v" , cl . imageName )
}
}
2015-02-03 20:14:16 +00:00
2015-04-13 22:25:14 +00:00
type podsByID [ ] * kubecontainer . Pod
func ( b podsByID ) Len ( ) int { return len ( b ) }
func ( b podsByID ) Swap ( i , j int ) { b [ i ] , b [ j ] = b [ j ] , b [ i ] }
func ( b podsByID ) Less ( i , j int ) bool { return b [ i ] . ID < b [ j ] . ID }
type containersByID [ ] * kubecontainer . Container
func ( b containersByID ) Len ( ) int { return len ( b ) }
func ( b containersByID ) Swap ( i , j int ) { b [ i ] , b [ j ] = b [ j ] , b [ i ] }
func ( b containersByID ) Less ( i , j int ) bool { return b [ i ] . ID < b [ j ] . ID }
2015-03-04 01:33:48 +00:00
func TestFindContainersByPod ( t * testing . T ) {
tests := [ ] struct {
2015-04-13 22:25:14 +00:00
containerList [ ] docker . APIContainers
exitedContainerList [ ] docker . APIContainers
all bool
expectedPods [ ] * kubecontainer . Pod
2015-03-04 01:33:48 +00:00
} {
2015-04-13 22:25:14 +00:00
2015-03-04 01:33:48 +00:00
{
2015-04-13 22:25:14 +00:00
[ ] docker . APIContainers {
{
2015-03-04 01:33:48 +00:00
ID : "foobar" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_foobar.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
2015-03-04 01:33:48 +00:00
ID : "barbar" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_barbar.1234_qux_ns_2343_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
2015-03-04 01:33:48 +00:00
ID : "baz" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_baz.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
} ,
2015-04-13 22:25:14 +00:00
[ ] docker . APIContainers {
{
ID : "barfoo" ,
Names : [ ] string { "/k8s_barfoo.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
ID : "bazbaz" ,
Names : [ ] string { "/k8s_bazbaz.1234_qux_ns_5678_42" } ,
2015-03-04 01:33:48 +00:00
} ,
} ,
2015-04-13 22:25:14 +00:00
false ,
[ ] * kubecontainer . Pod {
{
ID : "1234" ,
Name : "qux" ,
Namespace : "ns" ,
Containers : [ ] * kubecontainer . Container {
{
ID : "foobar" ,
Name : "foobar" ,
Hash : 0x1234 ,
} ,
{
ID : "baz" ,
Name : "baz" ,
Hash : 0x1234 ,
} ,
} ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
ID : "2343" ,
Name : "qux" ,
Namespace : "ns" ,
Containers : [ ] * kubecontainer . Container {
{
ID : "barbar" ,
Name : "barbar" ,
Hash : 0x1234 ,
} ,
} ,
2015-03-04 01:33:48 +00:00
} ,
} ,
} ,
{
2015-04-13 22:25:14 +00:00
[ ] docker . APIContainers {
{
2015-03-04 01:33:48 +00:00
ID : "foobar" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_foobar.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
2015-03-04 01:33:48 +00:00
ID : "barbar" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_barbar.1234_qux_ns_2343_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
2015-03-04 01:33:48 +00:00
ID : "baz" ,
2015-04-13 22:25:14 +00:00
Names : [ ] string { "/k8s_baz.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
} ,
2015-04-13 22:25:14 +00:00
[ ] docker . APIContainers {
{
ID : "barfoo" ,
Names : [ ] string { "/k8s_barfoo.1234_qux_ns_1234_42" } ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
ID : "bazbaz" ,
Names : [ ] string { "/k8s_bazbaz.1234_qux_ns_5678_42" } ,
2015-03-04 01:33:48 +00:00
} ,
} ,
2015-04-13 22:25:14 +00:00
true ,
[ ] * kubecontainer . Pod {
{
ID : "1234" ,
Name : "qux" ,
Namespace : "ns" ,
Containers : [ ] * kubecontainer . Container {
{
ID : "foobar" ,
Name : "foobar" ,
Hash : 0x1234 ,
} ,
{
ID : "barfoo" ,
Name : "barfoo" ,
Hash : 0x1234 ,
} ,
{
ID : "baz" ,
Name : "baz" ,
Hash : 0x1234 ,
} ,
} ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
ID : "2343" ,
Name : "qux" ,
Namespace : "ns" ,
Containers : [ ] * kubecontainer . Container {
{
ID : "barbar" ,
Name : "barbar" ,
Hash : 0x1234 ,
} ,
} ,
2015-03-04 01:33:48 +00:00
} ,
2015-04-13 22:25:14 +00:00
{
ID : "5678" ,
Name : "qux" ,
Namespace : "ns" ,
Containers : [ ] * kubecontainer . Container {
{
ID : "bazbaz" ,
Name : "bazbaz" ,
Hash : 0x1234 ,
} ,
} ,
2015-03-04 01:33:48 +00:00
} ,
} ,
} ,
2015-04-13 22:25:14 +00:00
{
[ ] docker . APIContainers { } ,
[ ] docker . APIContainers { } ,
true ,
nil ,
} ,
2015-03-04 01:33:48 +00:00
}
2015-04-13 22:25:14 +00:00
fakeClient := & FakeDockerClient { }
2015-04-28 18:02:29 +00:00
np , _ := network . InitNetworkPlugin ( [ ] network . NetworkPlugin { } , "" , network . NewFakeHost ( nil ) )
2015-05-01 22:25:11 +00:00
containerManager := NewFakeDockerManager ( fakeClient , & record . FakeRecorder { } , nil , nil , PodInfraContainerImage , 0 , 0 , "" , kubecontainer . FakeOS { } , np , nil , nil , nil )
2015-04-13 22:25:14 +00:00
for i , test := range tests {
fakeClient . ContainerList = test . containerList
fakeClient . ExitedContainerList = test . exitedContainerList
result , _ := containerManager . GetPods ( test . all )
for i := range result {
sort . Sort ( containersByID ( result [ i ] . Containers ) )
}
for i := range test . expectedPods {
sort . Sort ( containersByID ( test . expectedPods [ i ] . Containers ) )
}
sort . Sort ( podsByID ( result ) )
sort . Sort ( podsByID ( test . expectedPods ) )
if ! reflect . DeepEqual ( test . expectedPods , result ) {
t . Errorf ( "%d: expected: %#v, saw: %#v" , i , test . expectedPods , result )
2015-03-04 01:33:48 +00:00
}
}
}
2015-03-26 18:59:41 +00:00
func TestMakePortsAndBindings ( t * testing . T ) {
2015-05-12 21:49:35 +00:00
ports := [ ] kubecontainer . PortMapping {
{
ContainerPort : 80 ,
HostPort : 8080 ,
HostIP : "127.0.0.1" ,
} ,
{
ContainerPort : 443 ,
HostPort : 443 ,
Protocol : "tcp" ,
} ,
{
ContainerPort : 444 ,
HostPort : 444 ,
Protocol : "udp" ,
} ,
{
ContainerPort : 445 ,
HostPort : 445 ,
Protocol : "foobar" ,
2015-03-26 18:59:41 +00:00
} ,
}
2015-05-12 21:49:35 +00:00
exposedPorts , bindings := makePortsAndBindings ( ports )
if len ( ports ) != len ( exposedPorts ) ||
len ( ports ) != len ( bindings ) {
t . Errorf ( "Unexpected ports and bindings, %#v %#v %#v" , ports , exposedPorts , bindings )
2015-03-26 18:59:41 +00:00
}
for key , value := range bindings {
switch value [ 0 ] . HostPort {
case "8080" :
if ! reflect . DeepEqual ( docker . Port ( "80/tcp" ) , key ) {
t . Errorf ( "Unexpected docker port: %#v" , key )
}
if value [ 0 ] . HostIP != "127.0.0.1" {
t . Errorf ( "Unexpected host IP: %s" , value [ 0 ] . HostIP )
}
case "443" :
if ! reflect . DeepEqual ( docker . Port ( "443/tcp" ) , key ) {
t . Errorf ( "Unexpected docker port: %#v" , key )
}
if value [ 0 ] . HostIP != "" {
t . Errorf ( "Unexpected host IP: %s" , value [ 0 ] . HostIP )
}
case "444" :
if ! reflect . DeepEqual ( docker . Port ( "444/udp" ) , key ) {
t . Errorf ( "Unexpected docker port: %#v" , key )
}
if value [ 0 ] . HostIP != "" {
t . Errorf ( "Unexpected host IP: %s" , value [ 0 ] . HostIP )
}
case "445" :
if ! reflect . DeepEqual ( docker . Port ( "445/tcp" ) , key ) {
t . Errorf ( "Unexpected docker port: %#v" , key )
}
if value [ 0 ] . HostIP != "" {
t . Errorf ( "Unexpected host IP: %s" , value [ 0 ] . HostIP )
}
}
}
}