1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
// Copyright 2013 Canonical Ltd.
// Copyright 2014 Cloudbase Solutions SRL
// Licensed under the LGPLv3, see LICENCE file for details.
package checkers
import (
"fmt"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
gc "gopkg.in/check.v1"
)
// IsNonEmptyFile checker
type isNonEmptyFileChecker struct {
*gc.CheckerInfo
}
var IsNonEmptyFile gc.Checker = &isNonEmptyFileChecker{
&gc.CheckerInfo{Name: "IsNonEmptyFile", Params: []string{"obtained"}},
}
func (checker *isNonEmptyFileChecker) Check(params []interface{}, names []string) (result bool, error string) {
filename, isString := stringOrStringer(params[0])
if isString {
fileInfo, err := os.Stat(filename)
if os.IsNotExist(err) {
return false, fmt.Sprintf("%s does not exist", filename)
} else if err != nil {
return false, fmt.Sprintf("other stat error: %v", err)
}
if fileInfo.Size() > 0 {
return true, ""
} else {
return false, fmt.Sprintf("%s is empty", filename)
}
}
value := reflect.ValueOf(params[0])
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
}
// IsDirectory checker
type isDirectoryChecker struct {
*gc.CheckerInfo
}
var IsDirectory gc.Checker = &isDirectoryChecker{
&gc.CheckerInfo{Name: "IsDirectory", Params: []string{"obtained"}},
}
func (checker *isDirectoryChecker) Check(params []interface{}, names []string) (result bool, error string) {
path, isString := stringOrStringer(params[0])
if isString {
fileInfo, err := os.Stat(path)
if os.IsNotExist(err) {
return false, fmt.Sprintf("%s does not exist", path)
} else if err != nil {
return false, fmt.Sprintf("other stat error: %v", err)
}
if fileInfo.IsDir() {
return true, ""
} else {
return false, fmt.Sprintf("%s is not a directory", path)
}
}
value := reflect.ValueOf(params[0])
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
}
// IsSymlink checker
type isSymlinkChecker struct {
*gc.CheckerInfo
}
var IsSymlink gc.Checker = &isSymlinkChecker{
&gc.CheckerInfo{Name: "IsSymlink", Params: []string{"obtained"}},
}
func (checker *isSymlinkChecker) Check(params []interface{}, names []string) (result bool, error string) {
path, isString := stringOrStringer(params[0])
if isString {
fileInfo, err := os.Lstat(path)
if os.IsNotExist(err) {
return false, fmt.Sprintf("%s does not exist", path)
} else if err != nil {
return false, fmt.Sprintf("other stat error: %v", err)
}
if fileInfo.Mode()&os.ModeSymlink != 0 {
return true, ""
} else {
return false, fmt.Sprintf("%s is not a symlink: %+v", path, fileInfo)
}
}
value := reflect.ValueOf(params[0])
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
}
// DoesNotExist checker makes sure the path specified doesn't exist.
type doesNotExistChecker struct {
*gc.CheckerInfo
}
var DoesNotExist gc.Checker = &doesNotExistChecker{
&gc.CheckerInfo{Name: "DoesNotExist", Params: []string{"obtained"}},
}
func (checker *doesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) {
path, isString := stringOrStringer(params[0])
if isString {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return true, ""
} else if err != nil {
return false, fmt.Sprintf("other stat error: %v", err)
}
return false, fmt.Sprintf("%s exists", path)
}
value := reflect.ValueOf(params[0])
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
}
// SymlinkDoesNotExist checker makes sure the path specified doesn't exist.
type symlinkDoesNotExistChecker struct {
*gc.CheckerInfo
}
var SymlinkDoesNotExist gc.Checker = &symlinkDoesNotExistChecker{
&gc.CheckerInfo{Name: "SymlinkDoesNotExist", Params: []string{"obtained"}},
}
func (checker *symlinkDoesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) {
path, isString := stringOrStringer(params[0])
if isString {
_, err := os.Lstat(path)
if os.IsNotExist(err) {
return true, ""
} else if err != nil {
return false, fmt.Sprintf("other stat error: %v", err)
}
return false, fmt.Sprintf("%s exists", path)
}
value := reflect.ValueOf(params[0])
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
}
// Same path checker -- will check that paths are the same OS indepentent
type samePathChecker struct {
*gc.CheckerInfo
}
// SamePath checks paths to see whether they're the same, can follow symlinks and is OS independent
var SamePath gc.Checker = &samePathChecker{
&gc.CheckerInfo{Name: "SamePath", Params: []string{"obtained", "expected"}},
}
func (checker *samePathChecker) Check(params []interface{}, names []string) (result bool, error string) {
// Check for panics
defer func() {
if panicked := recover(); panicked != nil {
result = false
error = fmt.Sprint(panicked)
}
}()
// Convert input
obtained, isStr := stringOrStringer(params[0])
if !isStr {
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %T:%#v", params[0], params[0])
}
expected, isStr := stringOrStringer(params[1])
if !isStr {
return false, fmt.Sprintf("obtained value is not a string and has no .String(), %T:%#v", params[1], params[1])
}
// Convert paths to proper format
obtained = filepath.FromSlash(obtained)
expected = filepath.FromSlash(expected)
// If running on Windows, paths will be case-insensitive and thus we
// normalize the inputs to a default of all upper-case
if runtime.GOOS == "windows" {
obtained = strings.ToUpper(obtained)
expected = strings.ToUpper(expected)
}
// Same path do not check further
if obtained == expected {
return true, ""
}
// If it's not the same path, check if it points to the same file.
// Thus, the cases with windows-shortened paths are accounted for
// This will throw an error if it's not a file
ob, err := os.Stat(obtained)
if err != nil {
return false, err.Error()
}
ex, err := os.Stat(expected)
if err != nil {
return false, err.Error()
}
res := os.SameFile(ob, ex)
if res {
return true, ""
}
return false, fmt.Sprintf("Not the same file")
}
|