2018-02-05 21:05:59 +00:00
package client // import "github.com/docker/docker/client"
2016-09-06 18:46:37 +00:00
import (
"bytes"
2018-04-19 22:30:59 +00:00
"context"
2016-09-06 18:46:37 +00:00
"fmt"
2021-08-24 10:10:50 +00:00
"io"
2016-09-06 18:46:37 +00:00
"net/http"
"reflect"
"strings"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
2018-12-31 17:22:43 +00:00
"github.com/docker/docker/errdefs"
2019-08-05 14:37:47 +00:00
units "github.com/docker/go-units"
2016-09-06 18:46:37 +00:00
)
func TestImageBuildError ( t * testing . T ) {
client := & Client {
2016-09-09 03:44:25 +00:00
client : newMockClient ( errorMock ( http . StatusInternalServerError , "Server error" ) ) ,
2016-09-06 18:46:37 +00:00
}
_ , err := client . ImageBuild ( context . Background ( ) , nil , types . ImageBuildOptions { } )
2018-12-31 17:22:43 +00:00
if ! errdefs . IsSystem ( err ) {
2019-10-12 22:31:53 +00:00
t . Fatalf ( "expected a Server Error, got %[1]T: %[1]v" , err )
2018-12-31 17:22:43 +00:00
}
2016-09-06 18:46:37 +00:00
}
func TestImageBuild ( t * testing . T ) {
2016-12-03 13:46:04 +00:00
v1 := "value1"
v2 := "value2"
2016-09-06 18:46:37 +00:00
emptyRegistryConfig := "bnVsbA=="
buildCases := [ ] struct {
buildOptions types . ImageBuildOptions
expectedQueryParams map [ string ] string
expectedTags [ ] string
expectedRegistryConfig string
} {
{
buildOptions : types . ImageBuildOptions {
SuppressOutput : true ,
NoCache : true ,
Remove : true ,
ForceRemove : true ,
PullParent : true ,
} ,
expectedQueryParams : map [ string ] string {
"q" : "1" ,
"nocache" : "1" ,
"rm" : "1" ,
"forcerm" : "1" ,
"pull" : "1" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : emptyRegistryConfig ,
} ,
{
buildOptions : types . ImageBuildOptions {
SuppressOutput : false ,
NoCache : false ,
Remove : false ,
ForceRemove : false ,
PullParent : false ,
} ,
expectedQueryParams : map [ string ] string {
"q" : "" ,
"nocache" : "" ,
"rm" : "0" ,
"forcerm" : "" ,
"pull" : "" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : emptyRegistryConfig ,
} ,
{
buildOptions : types . ImageBuildOptions {
RemoteContext : "remoteContext" ,
Isolation : container . Isolation ( "isolation" ) ,
CPUSetCPUs : "2" ,
CPUSetMems : "12" ,
CPUShares : 20 ,
CPUQuota : 10 ,
CPUPeriod : 30 ,
Memory : 256 ,
MemorySwap : 512 ,
ShmSize : 10 ,
CgroupParent : "cgroup_parent" ,
Dockerfile : "Dockerfile" ,
} ,
expectedQueryParams : map [ string ] string {
"remote" : "remoteContext" ,
"isolation" : "isolation" ,
"cpusetcpus" : "2" ,
"cpusetmems" : "12" ,
"cpushares" : "20" ,
"cpuquota" : "10" ,
"cpuperiod" : "30" ,
"memory" : "256" ,
"memswap" : "512" ,
"shmsize" : "10" ,
"cgroupparent" : "cgroup_parent" ,
"dockerfile" : "Dockerfile" ,
"rm" : "0" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : emptyRegistryConfig ,
} ,
{
buildOptions : types . ImageBuildOptions {
2016-12-03 13:46:04 +00:00
BuildArgs : map [ string ] * string {
"ARG1" : & v1 ,
"ARG2" : & v2 ,
"ARG3" : nil ,
2016-09-06 18:46:37 +00:00
} ,
} ,
expectedQueryParams : map [ string ] string {
2016-12-03 13:46:04 +00:00
"buildargs" : ` { "ARG1":"value1","ARG2":"value2","ARG3":null} ` ,
2016-09-06 18:46:37 +00:00
"rm" : "0" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : emptyRegistryConfig ,
} ,
{
buildOptions : types . ImageBuildOptions {
Ulimits : [ ] * units . Ulimit {
{
Name : "nproc" ,
Hard : 65557 ,
Soft : 65557 ,
} ,
{
Name : "nofile" ,
Hard : 20000 ,
Soft : 40000 ,
} ,
} ,
} ,
expectedQueryParams : map [ string ] string {
"ulimits" : ` [ { "Name":"nproc","Hard":65557,"Soft":65557}, { "Name":"nofile","Hard":20000,"Soft":40000}] ` ,
"rm" : "0" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : emptyRegistryConfig ,
} ,
{
buildOptions : types . ImageBuildOptions {
AuthConfigs : map [ string ] types . AuthConfig {
"https://index.docker.io/v1/" : {
Auth : "dG90bwo=" ,
} ,
} ,
} ,
expectedQueryParams : map [ string ] string {
"rm" : "0" ,
} ,
expectedTags : [ ] string { } ,
expectedRegistryConfig : "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289In19" ,
} ,
}
for _ , buildCase := range buildCases {
expectedURL := "/build"
client := & Client {
2016-09-09 03:44:25 +00:00
client : newMockClient ( func ( r * http . Request ) ( * http . Response , error ) {
2016-09-06 18:46:37 +00:00
if ! strings . HasPrefix ( r . URL . Path , expectedURL ) {
return nil , fmt . Errorf ( "Expected URL '%s', got '%s'" , expectedURL , r . URL )
}
// Check request headers
registryConfig := r . Header . Get ( "X-Registry-Config" )
if registryConfig != buildCase . expectedRegistryConfig {
return nil , fmt . Errorf ( "X-Registry-Config header not properly set in the request. Expected '%s', got %s" , buildCase . expectedRegistryConfig , registryConfig )
}
contentType := r . Header . Get ( "Content-Type" )
2016-12-06 21:15:27 +00:00
if contentType != "application/x-tar" {
return nil , fmt . Errorf ( "Content-type header not properly set in the request. Expected 'application/x-tar', got %s" , contentType )
2016-09-06 18:46:37 +00:00
}
// Check query parameters
query := r . URL . Query ( )
for key , expected := range buildCase . expectedQueryParams {
actual := query . Get ( key )
if actual != expected {
return nil , fmt . Errorf ( "%s not set in URL query properly. Expected '%s', got %s" , key , expected , actual )
}
}
// Check tags
if len ( buildCase . expectedTags ) > 0 {
tags := query [ "t" ]
if ! reflect . DeepEqual ( tags , buildCase . expectedTags ) {
return nil , fmt . Errorf ( "t (tags) not set in URL query properly. Expected '%s', got %s" , buildCase . expectedTags , tags )
}
}
headers := http . Header { }
headers . Add ( "Server" , "Docker/v1.23 (MyOS)" )
return & http . Response {
StatusCode : http . StatusOK ,
2021-08-24 10:10:50 +00:00
Body : io . NopCloser ( bytes . NewReader ( [ ] byte ( "body" ) ) ) ,
2016-09-06 18:46:37 +00:00
Header : headers ,
} , nil
} ) ,
}
buildResponse , err := client . ImageBuild ( context . Background ( ) , nil , buildCase . buildOptions )
if err != nil {
t . Fatal ( err )
}
if buildResponse . OSType != "MyOS" {
t . Fatalf ( "expected OSType to be 'MyOS', got %s" , buildResponse . OSType )
}
2021-08-24 10:10:50 +00:00
response , err := io . ReadAll ( buildResponse . Body )
2016-09-06 18:46:37 +00:00
if err != nil {
t . Fatal ( err )
}
buildResponse . Body . Close ( )
if string ( response ) != "body" {
t . Fatalf ( "expected Body to contain 'body' string, got %s" , response )
}
}
}
func TestGetDockerOS ( t * testing . T ) {
cases := map [ string ] string {
"Docker/v1.22 (linux)" : "linux" ,
"Docker/v1.22 (windows)" : "windows" ,
"Foo/v1.22 (bar)" : "" ,
}
for header , os := range cases {
2016-11-09 22:46:53 +00:00
g := getDockerOS ( header )
2016-09-06 18:46:37 +00:00
if g != os {
t . Fatalf ( "Expected %s, got %s" , os , g )
}
}
}