2018-02-05 16:05:59 -05:00
package client // import "github.com/docker/docker/client"
2016-09-06 14:46:37 -04:00
import (
"bytes"
2018-04-19 18:30:59 -04:00
"context"
2016-09-06 14:46:37 -04:00
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"testing"
"github.com/docker/docker/api/types"
2018-12-31 12:22:43 -05:00
"github.com/docker/docker/errdefs"
2016-09-06 14:46:37 -04:00
)
func TestContainerStatPathError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( errorMock ( http . StatusInternalServerError , "Server error" ) ) ,
2016-09-06 14:46:37 -04:00
}
_ , err := client . ContainerStatPath ( context . Background ( ) , "container_id" , "path" )
if err == nil || err . Error ( ) != "Error response from daemon: Server error" {
t . Fatalf ( "expected a Server error, got %v" , err )
}
2018-12-31 12:22:43 -05:00
if ! errdefs . IsSystem ( err ) {
t . Fatalf ( "expected a Server Error, got %T" , err )
}
2016-09-06 14:46:37 -04:00
}
2018-01-11 07:15:46 -05:00
func TestContainerStatPathNotFoundError ( t * testing . T ) {
client := & Client {
client : newMockClient ( errorMock ( http . StatusNotFound , "Not found" ) ) ,
}
_ , err := client . ContainerStatPath ( context . Background ( ) , "container_id" , "path" )
if ! IsErrNotFound ( err ) {
t . Fatalf ( "expected a not found error, got %v" , err )
}
}
2016-09-06 14:46:37 -04:00
func TestContainerStatPathNoHeaderError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( func ( req * http . Request ) ( * http . Response , error ) {
2016-09-06 14:46:37 -04:00
return & http . Response {
StatusCode : http . StatusOK ,
Body : ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) ,
} , nil
} ) ,
}
_ , err := client . ContainerStatPath ( context . Background ( ) , "container_id" , "path/to/file" )
if err == nil {
t . Fatalf ( "expected an error, got nothing" )
}
}
func TestContainerStatPath ( t * testing . T ) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( func ( req * http . Request ) ( * http . Response , error ) {
2016-09-06 14:46:37 -04:00
if ! strings . HasPrefix ( req . URL . Path , expectedURL ) {
return nil , fmt . Errorf ( "Expected URL '%s', got '%s'" , expectedURL , req . URL )
}
if req . Method != "HEAD" {
return nil , fmt . Errorf ( "expected HEAD method, got %s" , req . Method )
}
query := req . URL . Query ( )
path := query . Get ( "path" )
if path != expectedPath {
return nil , fmt . Errorf ( "path not set in URL query properly" )
}
content , err := json . Marshal ( types . ContainerPathStat {
Name : "name" ,
Mode : 0700 ,
} )
if err != nil {
return nil , err
}
base64PathStat := base64 . StdEncoding . EncodeToString ( content )
return & http . Response {
StatusCode : http . StatusOK ,
Body : ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) ,
Header : http . Header {
"X-Docker-Container-Path-Stat" : [ ] string { base64PathStat } ,
} ,
} , nil
} ) ,
}
stat , err := client . ContainerStatPath ( context . Background ( ) , "container_id" , expectedPath )
if err != nil {
t . Fatal ( err )
}
if stat . Name != "name" {
2016-12-01 14:32:04 -05:00
t . Fatalf ( "expected container path stat name to be 'name', got '%s'" , stat . Name )
2016-09-06 14:46:37 -04:00
}
if stat . Mode != 0700 {
2016-12-01 14:32:04 -05:00
t . Fatalf ( "expected container path stat mode to be 0700, got '%v'" , stat . Mode )
2016-09-06 14:46:37 -04:00
}
}
func TestCopyToContainerError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( errorMock ( http . StatusInternalServerError , "Server error" ) ) ,
2016-09-06 14:46:37 -04:00
}
err := client . CopyToContainer ( context . Background ( ) , "container_id" , "path/to/file" , bytes . NewReader ( [ ] byte ( "" ) ) , types . CopyToContainerOptions { } )
if err == nil || err . Error ( ) != "Error response from daemon: Server error" {
t . Fatalf ( "expected a Server error, got %v" , err )
}
2018-12-31 12:22:43 -05:00
if ! errdefs . IsSystem ( err ) {
t . Fatalf ( "expected a Server Error, got %T" , err )
}
2016-09-06 14:46:37 -04:00
}
2018-01-11 07:15:46 -05:00
func TestCopyToContainerNotFoundError ( t * testing . T ) {
client := & Client {
client : newMockClient ( errorMock ( http . StatusNotFound , "Not found" ) ) ,
}
err := client . CopyToContainer ( context . Background ( ) , "container_id" , "path/to/file" , bytes . NewReader ( [ ] byte ( "" ) ) , types . CopyToContainerOptions { } )
if ! IsErrNotFound ( err ) {
t . Fatalf ( "expected a not found error, got %v" , err )
}
}
2019-02-09 13:19:22 -05:00
// TODO TestCopyToContainerNotStatusOKError expects a non-error status-code ("204 No Content") to produce an error; verify if this is the desired behavior
2016-09-06 14:46:37 -04:00
func TestCopyToContainerNotStatusOKError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( errorMock ( http . StatusNoContent , "No content" ) ) ,
2016-09-06 14:46:37 -04:00
}
err := client . CopyToContainer ( context . Background ( ) , "container_id" , "path/to/file" , bytes . NewReader ( [ ] byte ( "" ) ) , types . CopyToContainerOptions { } )
if err == nil || err . Error ( ) != "unexpected status code from daemon: 204" {
t . Fatalf ( "expected an unexpected status code error, got %v" , err )
}
}
func TestCopyToContainer ( t * testing . T ) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( func ( req * http . Request ) ( * http . Response , error ) {
2016-09-06 14:46:37 -04:00
if ! strings . HasPrefix ( req . URL . Path , expectedURL ) {
return nil , fmt . Errorf ( "Expected URL '%s', got '%s'" , expectedURL , req . URL )
}
if req . Method != "PUT" {
return nil , fmt . Errorf ( "expected PUT method, got %s" , req . Method )
}
query := req . URL . Query ( )
path := query . Get ( "path" )
if path != expectedPath {
return nil , fmt . Errorf ( "path not set in URL query properly, expected '%s', got %s" , expectedPath , path )
}
noOverwriteDirNonDir := query . Get ( "noOverwriteDirNonDir" )
if noOverwriteDirNonDir != "true" {
return nil , fmt . Errorf ( "noOverwriteDirNonDir not set in URL query properly, expected true, got %s" , noOverwriteDirNonDir )
}
content , err := ioutil . ReadAll ( req . Body )
if err != nil {
return nil , err
}
if err := req . Body . Close ( ) ; err != nil {
return nil , err
}
if string ( content ) != "content" {
return nil , fmt . Errorf ( "expected content to be 'content', got %s" , string ( content ) )
}
return & http . Response {
StatusCode : http . StatusOK ,
Body : ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) ,
} , nil
} ) ,
}
err := client . CopyToContainer ( context . Background ( ) , "container_id" , expectedPath , bytes . NewReader ( [ ] byte ( "content" ) ) , types . CopyToContainerOptions {
AllowOverwriteDirWithFile : false ,
} )
if err != nil {
t . Fatal ( err )
}
}
func TestCopyFromContainerError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( errorMock ( http . StatusInternalServerError , "Server error" ) ) ,
2016-09-06 14:46:37 -04:00
}
_ , _ , err := client . CopyFromContainer ( context . Background ( ) , "container_id" , "path/to/file" )
if err == nil || err . Error ( ) != "Error response from daemon: Server error" {
t . Fatalf ( "expected a Server error, got %v" , err )
}
2018-12-31 12:22:43 -05:00
if ! errdefs . IsSystem ( err ) {
t . Fatalf ( "expected a Server Error, got %T" , err )
}
2016-09-06 14:46:37 -04:00
}
2018-01-11 07:15:46 -05:00
func TestCopyFromContainerNotFoundError ( t * testing . T ) {
client := & Client {
client : newMockClient ( errorMock ( http . StatusNotFound , "Not found" ) ) ,
}
_ , _ , err := client . CopyFromContainer ( context . Background ( ) , "container_id" , "path/to/file" )
if ! IsErrNotFound ( err ) {
t . Fatalf ( "expected a not found error, got %v" , err )
}
}
2019-02-09 13:19:22 -05:00
// TODO TestCopyFromContainerNotStatusOKError expects a non-error status-code ("204 No Content") to produce an error; verify if this is the desired behavior
2016-09-06 14:46:37 -04:00
func TestCopyFromContainerNotStatusOKError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( errorMock ( http . StatusNoContent , "No content" ) ) ,
2016-09-06 14:46:37 -04:00
}
_ , _ , err := client . CopyFromContainer ( context . Background ( ) , "container_id" , "path/to/file" )
if err == nil || err . Error ( ) != "unexpected status code from daemon: 204" {
t . Fatalf ( "expected an unexpected status code error, got %v" , err )
}
}
func TestCopyFromContainerNoHeaderError ( t * testing . T ) {
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( func ( req * http . Request ) ( * http . Response , error ) {
2016-09-06 14:46:37 -04:00
return & http . Response {
StatusCode : http . StatusOK ,
Body : ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) ,
} , nil
} ) ,
}
_ , _ , err := client . CopyFromContainer ( context . Background ( ) , "container_id" , "path/to/file" )
if err == nil {
t . Fatalf ( "expected an error, got nothing" )
}
}
func TestCopyFromContainer ( t * testing . T ) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := & Client {
2016-09-08 23:44:25 -04:00
client : newMockClient ( func ( req * http . Request ) ( * http . Response , error ) {
2016-09-06 14:46:37 -04:00
if ! strings . HasPrefix ( req . URL . Path , expectedURL ) {
return nil , fmt . Errorf ( "Expected URL '%s', got '%s'" , expectedURL , req . URL )
}
if req . Method != "GET" {
2016-11-17 02:50:38 -05:00
return nil , fmt . Errorf ( "expected GET method, got %s" , req . Method )
2016-09-06 14:46:37 -04:00
}
query := req . URL . Query ( )
path := query . Get ( "path" )
if path != expectedPath {
return nil , fmt . Errorf ( "path not set in URL query properly, expected '%s', got %s" , expectedPath , path )
}
headercontent , err := json . Marshal ( types . ContainerPathStat {
Name : "name" ,
Mode : 0700 ,
} )
if err != nil {
return nil , err
}
base64PathStat := base64 . StdEncoding . EncodeToString ( headercontent )
return & http . Response {
StatusCode : http . StatusOK ,
Body : ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "content" ) ) ) ,
Header : http . Header {
"X-Docker-Container-Path-Stat" : [ ] string { base64PathStat } ,
} ,
} , nil
} ) ,
}
r , stat , err := client . CopyFromContainer ( context . Background ( ) , "container_id" , expectedPath )
if err != nil {
t . Fatal ( err )
}
if stat . Name != "name" {
2016-12-01 14:32:04 -05:00
t . Fatalf ( "expected container path stat name to be 'name', got '%s'" , stat . Name )
2016-09-06 14:46:37 -04:00
}
if stat . Mode != 0700 {
2016-12-01 14:32:04 -05:00
t . Fatalf ( "expected container path stat mode to be 0700, got '%v'" , stat . Mode )
2016-09-06 14:46:37 -04:00
}
content , err := ioutil . ReadAll ( r )
if err != nil {
t . Fatal ( err )
}
if err := r . Close ( ) ; err != nil {
t . Fatal ( err )
}
if string ( content ) != "content" {
t . Fatalf ( "expected content to be 'content', got %s" , string ( content ) )
}
}