github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/testutil/filecontentchecker.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2015-2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package testutil 21 22 import ( 23 "bytes" 24 "fmt" 25 "io/ioutil" 26 "regexp" 27 "strings" 28 29 "gopkg.in/check.v1" 30 ) 31 32 type fileContentChecker struct { 33 *check.CheckerInfo 34 exact bool 35 } 36 37 // FileEquals verifies that the given file's content is equal 38 // to the string (or fmt.Stringer) or []byte provided. 39 var FileEquals check.Checker = &fileContentChecker{ 40 CheckerInfo: &check.CheckerInfo{Name: "FileEquals", Params: []string{"filename", "contents"}}, 41 exact: true, 42 } 43 44 // FileContains verifies that the given file's content contains 45 // the string (or fmt.Stringer) or []byte provided. 46 var FileContains check.Checker = &fileContentChecker{ 47 CheckerInfo: &check.CheckerInfo{Name: "FileContains", Params: []string{"filename", "contents"}}, 48 } 49 50 // FileMatches verifies that the given file's content matches 51 // the string provided. 52 var FileMatches check.Checker = &fileContentChecker{ 53 CheckerInfo: &check.CheckerInfo{Name: "FileMatches", Params: []string{"filename", "regex"}}, 54 } 55 56 func (c *fileContentChecker) Check(params []interface{}, names []string) (result bool, error string) { 57 filename, ok := params[0].(string) 58 if !ok { 59 return false, "Filename must be a string" 60 } 61 if names[1] == "regex" { 62 regexpr, ok := params[1].(string) 63 if !ok { 64 return false, "Regex must be a string" 65 } 66 rx, err := regexp.Compile(regexpr) 67 if err != nil { 68 return false, fmt.Sprintf("Cannot compile regexp %q: %v", regexpr, err) 69 } 70 params[1] = rx 71 } 72 return fileContentCheck(filename, params[1], c.exact) 73 } 74 75 func fileContentCheck(filename string, content interface{}, exact bool) (result bool, error string) { 76 buf, err := ioutil.ReadFile(filename) 77 if err != nil { 78 return false, fmt.Sprintf("Cannot read file %q: %v", filename, err) 79 } 80 presentableBuf := string(buf) 81 if exact { 82 switch content := content.(type) { 83 case string: 84 result = presentableBuf == content 85 case []byte: 86 result = bytes.Equal(buf, content) 87 presentableBuf = "<binary data>" 88 case fmt.Stringer: 89 result = presentableBuf == content.String() 90 default: 91 error = fmt.Sprintf("Cannot compare file contents with something of type %T", content) 92 } 93 } else { 94 switch content := content.(type) { 95 case string: 96 result = strings.Contains(presentableBuf, content) 97 case []byte: 98 result = bytes.Contains(buf, content) 99 presentableBuf = "<binary data>" 100 case *regexp.Regexp: 101 result = content.Match(buf) 102 case fmt.Stringer: 103 result = strings.Contains(presentableBuf, content.String()) 104 default: 105 error = fmt.Sprintf("Cannot compare file contents with something of type %T", content) 106 } 107 } 108 if !result { 109 if error == "" { 110 error = fmt.Sprintf("Failed to match with file contents:\n%v", presentableBuf) 111 } 112 return result, error 113 } 114 return result, "" 115 }