| 111 | } |
| 112 | |
| 113 | func alterFiles(dir string) error { |
| 114 | err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { |
| 115 | if os.IsNotExist(err) { |
| 116 | // Something we deleted. Never mind. |
| 117 | return nil |
| 118 | } |
| 119 | |
| 120 | info, err = os.Stat(path) |
| 121 | if err != nil { |
| 122 | // Something we deleted while walking. Ignore. |
| 123 | return nil |
| 124 | } |
| 125 | |
| 126 | if strings.HasPrefix(filepath.Base(path), "test-") { |
| 127 | return nil |
| 128 | } |
| 129 | |
| 130 | switch filepath.Base(path) { |
| 131 | case ".stfolder": |
| 132 | return nil |
| 133 | case ".stversions": |
| 134 | return nil |
| 135 | } |
| 136 | |
| 137 | // File structure is base/x/xy/xyz12345... |
| 138 | // comps == 1: base (don't touch) |
| 139 | // comps == 2: base/x (must be dir) |
| 140 | // comps == 3: base/x/xy (must be dir) |
| 141 | // comps > 3: base/x/xy/xyz12345... (can be dir or file) |
| 142 | |
| 143 | comps := len(strings.Split(path, string(os.PathSeparator))) |
| 144 | |
| 145 | r := rand.Intn(10) |
| 146 | switch { |
| 147 | case r == 0 && comps > 2: |
| 148 | // Delete every tenth file or directory, except top levels |
| 149 | return removeAll(path) |
| 150 | |
| 151 | case r == 1 && info.Mode().IsRegular(): |
| 152 | if info.Mode()&0o200 != 0o200 { |
| 153 | // Not owner writable. Fix. |
| 154 | if err = os.Chmod(path, 0o644); err != nil { |
| 155 | return err |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | // Overwrite a random kilobyte of every tenth file |
| 160 | fd, err := os.OpenFile(path, os.O_RDWR, 0o644) |
| 161 | if err != nil { |
| 162 | return err |
| 163 | } |
| 164 | if info.Size() > 1024 { |
| 165 | _, err = fd.Seek(rand.Int63n(info.Size()), os.SEEK_SET) |
| 166 | if err != nil { |
| 167 | return err |
| 168 | } |
| 169 | } |
| 170 | _, err = io.Copy(fd, io.LimitReader(cr.Reader, 1024)) |