1// +build linux 2 3/* 4** Zabbix 5** Copyright (C) 2001-2021 Zabbix SIA 6** 7** This program is free software; you can redistribute it and/or modify 8** it under the terms of the GNU General Public License as published by 9** the Free Software Foundation; either version 2 of the License, or 10** (at your option) any later version. 11** 12** This program is distributed in the hope that it will be useful, 13** but WITHOUT ANY WARRANTY; without even the implied warranty of 14** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15** GNU General Public License for more details. 16** 17** You should have received a copy of the GNU General Public License 18** along with this program; if not, write to the Free Software 19** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20**/ 21 22// package std is used to create wrappers for standard Go functions to support 23// mocking in tests where necessary 24package std 25 26import ( 27 "bytes" 28 "errors" 29 "os" 30 "syscall" 31 "time" 32 33 "golang.org/x/sys/unix" 34) 35 36// mocked os functionality 37 38type MockOs interface { 39 MockFile(path string, data []byte) 40} 41 42type fileTime struct { 43 ModTime time.Time 44} 45 46type mockOs struct { 47 files map[string][]byte 48 ftimes map[string]fileTime 49} 50 51type mockFile struct { 52 buffer *bytes.Buffer 53} 54 55type fileStat struct { 56 name string 57 size int64 58 mode FileMode 59 modTime time.Time 60 sys syscall.Stat_t 61} 62 63func (o *mockOs) Open(name string) (File, error) { 64 if data, ok := o.files[name]; !ok { 65 return nil, errors.New("file does not exist") 66 } else { 67 return &mockFile{bytes.NewBuffer(data)}, nil 68 } 69} 70 71func (o *fileStat) IsDir() bool { 72 return false 73} 74 75func (o *fileStat) Mode() os.FileMode { 76 return os.FileMode(o.mode) 77} 78 79func (o *fileStat) ModTime() time.Time { 80 return o.modTime 81} 82 83func (o *fileStat) Name() string { 84 return o.name 85} 86 87func (o *fileStat) Size() int64 { 88 return o.size 89} 90 91func (o *fileStat) Sys() interface{} { 92 return &o.sys 93} 94 95func (o *mockOs) Stat(name string) (os.FileInfo, error) { 96 if data, ok := o.files[name]; !ok { 97 return nil, os.ErrNotExist 98 } else { 99 var fs fileStat 100 101 fs.mode = 436 102 fs.modTime = o.ftimes[name].ModTime 103 fs.name = name 104 fs.size = int64(len(data)) 105 a, err := unix.TimeToTimespec(o.ftimes[name].ModTime) 106 if err != nil { 107 return nil, err 108 } 109 fs.sys.Atim.Sec = a.Sec 110 fs.sys.Ctim.Sec = a.Sec 111 112 return &fs, nil 113 } 114} 115 116func (o *mockOs) IsExist(err error) bool { 117 118 if err == nil { 119 return false 120 } 121 if err.Error() == "exists" { 122 return true 123 } 124 return false 125} 126 127func (f *mockFile) Close() error { 128 return nil 129} 130 131func (f *mockFile) Read(p []byte) (n int, err error) { 132 return f.buffer.Read(p) 133} 134 135// MockFile creates new mock file with the specified path and contents. 136func (o *mockOs) MockFile(path string, data []byte) { 137 o.files[path] = data 138 var ft fileTime 139 ft.ModTime = time.Now() 140 o.ftimes[path] = ft 141} 142 143// NewMockOs returns Os interface that replaces supported os package functionality with mock functions. 144func NewMockOs() Os { 145 return &mockOs{ 146 files: make(map[string][]byte), 147 ftimes: make(map[string]fileTime), 148 } 149} 150