2015-05-19 14:23:09 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2015-05-19 14:23:09 +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 mount
import (
"fmt"
2016-01-13 02:43:50 +00:00
"runtime"
2015-05-19 14:23:09 +00:00
"testing"
2017-07-19 05:58:53 +00:00
fakeexec "k8s.io/utils/exec/testing"
2015-05-19 14:23:09 +00:00
)
type ErrorMounter struct {
* FakeMounter
errIndex int
err [ ] error
}
func ( mounter * ErrorMounter ) Mount ( source string , target string , fstype string , options [ ] string ) error {
i := mounter . errIndex
mounter . errIndex ++
if mounter . err != nil && mounter . err [ i ] != nil {
return mounter . err [ i ]
}
return mounter . FakeMounter . Mount ( source , target , fstype , options )
}
type ExecArgs struct {
command string
args [ ] string
output string
err error
}
func TestSafeFormatAndMount ( t * testing . T ) {
2016-01-13 02:43:50 +00:00
if runtime . GOOS == "darwin" || runtime . GOOS == "windows" {
t . Skipf ( "not supported on GOOS=%s" , runtime . GOOS )
}
2015-05-19 14:23:09 +00:00
tests := [ ] struct {
2015-09-18 21:25:22 +00:00
description string
2015-05-19 14:23:09 +00:00
fstype string
mountOptions [ ] string
execScripts [ ] ExecArgs
mountErrs [ ] error
expectedError error
} {
2015-09-18 21:25:22 +00:00
{
description : "Test a read only mount" ,
2015-05-19 14:23:09 +00:00
fstype : "ext4" ,
mountOptions : [ ] string { "ro" } ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test a normal mount" ,
fstype : "ext4" ,
execScripts : [ ] ExecArgs {
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
} ,
2015-05-19 14:23:09 +00:00
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test 'fsck' fails with exit status 4" ,
fstype : "ext4" ,
execScripts : [ ] ExecArgs {
2017-07-19 05:58:53 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , & fakeexec . FakeExitError { Status : 4 } } ,
2015-09-18 21:25:22 +00:00
} ,
expectedError : fmt . Errorf ( "'fsck' found errors on device /dev/foo but could not correct them: ." ) ,
} ,
{
description : "Test 'fsck' fails with exit status 1 (errors found and corrected)" ,
fstype : "ext4" ,
execScripts : [ ] ExecArgs {
2017-07-19 05:58:53 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , & fakeexec . FakeExitError { Status : 1 } } ,
2015-09-18 21:25:22 +00:00
} ,
} ,
{
description : "Test 'fsck' fails with exit status other than 1 and 4 (likely unformatted device)" ,
fstype : "ext4" ,
execScripts : [ ] ExecArgs {
2017-07-19 05:58:53 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , & fakeexec . FakeExitError { Status : 8 } } ,
2015-09-18 21:25:22 +00:00
} ,
} ,
{
description : "Test that 'lsblk' is called and fails" ,
fstype : "ext4" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) } ,
2015-05-19 14:23:09 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "ext4\n" , nil } ,
2015-05-19 14:23:09 +00:00
} ,
expectedError : fmt . Errorf ( "unknown filesystem type '(null)'" ) ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test that 'lsblk' is called and confirms unformatted disk, format fails" ,
fstype : "ext4" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) } ,
2015-05-19 14:23:09 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n" , nil } ,
2016-12-18 10:08:51 +00:00
{ "mkfs.ext4" , [ ] string { "-F" , "/dev/foo" } , "" , fmt . Errorf ( "formatting failed" ) } ,
2015-05-19 14:23:09 +00:00
} ,
expectedError : fmt . Errorf ( "formatting failed" ) ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test that 'lsblk' is called and confirms unformatted disk, format passes, second mount fails" ,
fstype : "ext4" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) , fmt . Errorf ( "Still cannot mount" ) } ,
2015-05-19 14:23:09 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n" , nil } ,
2016-12-18 10:08:51 +00:00
{ "mkfs.ext4" , [ ] string { "-F" , "/dev/foo" } , "" , nil } ,
2015-05-19 14:23:09 +00:00
} ,
expectedError : fmt . Errorf ( "Still cannot mount" ) ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test that 'lsblk' is called and confirms unformatted disk, format passes, second mount passes" ,
fstype : "ext4" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) , nil } ,
2015-05-19 14:23:09 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n" , nil } ,
2016-12-18 10:08:51 +00:00
{ "mkfs.ext4" , [ ] string { "-F" , "/dev/foo" } , "" , nil } ,
2015-05-19 14:23:09 +00:00
} ,
expectedError : nil ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "Test that 'lsblk' is called and confirms unformatted disk, format passes, second mount passes with ext3" ,
fstype : "ext3" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) , nil } ,
2015-05-19 14:23:09 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n" , nil } ,
2016-12-18 10:08:51 +00:00
{ "mkfs.ext3" , [ ] string { "-F" , "/dev/foo" } , "" , nil } ,
2015-05-19 14:23:09 +00:00
} ,
expectedError : nil ,
} ,
2015-09-18 21:25:22 +00:00
{
description : "test that none ext4 fs does not get called with ext4 options." ,
fstype : "xfs" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) , nil } ,
2015-10-29 20:30:46 +00:00
execScripts : [ ] ExecArgs {
2015-09-18 21:25:22 +00:00
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
2017-03-20 12:08:13 +00:00
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n" , nil } ,
2015-10-29 20:30:46 +00:00
{ "mkfs.xfs" , [ ] string { "/dev/foo" } , "" , nil } ,
} ,
expectedError : nil ,
} ,
2017-03-20 12:08:13 +00:00
{
description : "Test that 'lsblk' is called and reports ext4 partition" ,
fstype : "ext3" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) } ,
execScripts : [ ] ExecArgs {
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\next4\n" , nil } ,
} ,
expectedError : fmt . Errorf ( "failed to mount the volume as \"ext3\", it already contains unknown data, probably partitions. Mount error: unknown filesystem type '(null)'" ) ,
} ,
{
description : "Test that 'lsblk' is called and reports empty partition" ,
fstype : "ext3" ,
mountErrs : [ ] error { fmt . Errorf ( "unknown filesystem type '(null)'" ) } ,
execScripts : [ ] ExecArgs {
{ "fsck" , [ ] string { "-a" , "/dev/foo" } , "" , nil } ,
{ "lsblk" , [ ] string { "-n" , "-o" , "FSTYPE" , "/dev/foo" } , "\n\n" , nil } ,
} ,
expectedError : fmt . Errorf ( "failed to mount the volume as \"ext3\", it already contains unknown data, probably partitions. Mount error: unknown filesystem type '(null)'" ) ,
} ,
2015-05-19 14:23:09 +00:00
}
for _ , test := range tests {
2017-08-14 10:16:27 +00:00
execCallCount := 0
execCallback := func ( cmd string , args ... string ) ( [ ] byte , error ) {
if len ( test . execScripts ) <= execCallCount {
t . Errorf ( "Unexpected command: %s %v" , cmd , args )
return nil , nil
}
script := test . execScripts [ execCallCount ]
execCallCount ++
if script . command != cmd {
t . Errorf ( "Unexpected command %s. Expecting %s" , cmd , script . command )
}
for j := range args {
if args [ j ] != script . args [ j ] {
t . Errorf ( "Unexpected args %v. Expecting %v" , args , script . args )
2015-05-19 14:23:09 +00:00
}
}
2017-08-14 10:16:27 +00:00
return [ ] byte ( script . output ) , script . err
2015-05-19 14:23:09 +00:00
}
fakeMounter := ErrorMounter { & FakeMounter { } , 0 , test . mountErrs }
2017-08-14 10:16:27 +00:00
fakeExec := NewFakeExec ( execCallback )
2015-05-19 14:23:09 +00:00
mounter := SafeFormatAndMount {
Interface : & fakeMounter ,
2017-08-14 10:16:27 +00:00
Exec : fakeExec ,
2015-05-19 14:23:09 +00:00
}
device := "/dev/foo"
dest := "/mnt/bar"
2015-11-05 21:49:40 +00:00
err := mounter . FormatAndMount ( device , dest , test . fstype , test . mountOptions )
2015-05-19 14:23:09 +00:00
if test . expectedError == nil {
if err != nil {
2015-09-18 21:25:22 +00:00
t . Errorf ( "test \"%s\" unexpected non-error: %v" , test . description , err )
2015-05-19 14:23:09 +00:00
}
// Check that something was mounted on the directory
isNotMountPoint , err := fakeMounter . IsLikelyNotMountPoint ( dest )
if err != nil || isNotMountPoint {
2015-09-18 21:25:22 +00:00
t . Errorf ( "test \"%s\" the directory was not mounted" , test . description )
2015-05-19 14:23:09 +00:00
}
//check that the correct device was mounted
mountedDevice , _ , err := GetDeviceNameFromMount ( fakeMounter . FakeMounter , dest )
if err != nil || mountedDevice != device {
2015-09-18 21:25:22 +00:00
t . Errorf ( "test \"%s\" the correct device was not mounted" , test . description )
2015-05-19 14:23:09 +00:00
}
} else {
if err == nil || test . expectedError . Error ( ) != err . Error ( ) {
2015-09-18 21:25:22 +00:00
t . Errorf ( "test \"%s\" unexpected error: \n [%v]. \nExpecting [%v]" , test . description , err , test . expectedError )
2015-05-19 14:23:09 +00:00
}
}
}
}