github.com/yogeshkumararora/slsa-github-generator@v1.10.1-0.20240520161934-11278bd5afb4/internal/utils/path_test.go (about) 1 // Copyright 2022 SLSA Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package utils 16 17 import ( 18 "errors" 19 "os" 20 "path/filepath" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/go-cmp/cmp/cmpopts" 25 ) 26 27 func Test_PathIsUnderCurrentDirectory(t *testing.T) { 28 t.Parallel() 29 30 tests := []struct { 31 expected error 32 name string 33 path string 34 }{ 35 { 36 name: "valid same path", 37 path: "./", 38 expected: nil, 39 }, 40 { 41 name: "valid path no slash", 42 path: "./some/valid/path", 43 expected: nil, 44 }, 45 { 46 name: "valid path with slash", 47 path: "./some/valid/path/", 48 expected: nil, 49 }, 50 { 51 name: "valid path with no dot", 52 path: "some/valid/path/", 53 expected: nil, 54 }, 55 { 56 name: "some valid path", 57 path: "../utils/some/valid/path", 58 expected: nil, 59 }, 60 { 61 name: "parent invalid path", 62 path: "../invalid/path", 63 expected: ErrInvalidPath, 64 }, 65 { 66 name: "some invalid fullpath", 67 path: "/some/invalid/fullpath", 68 expected: ErrInvalidPath, 69 }, 70 } 71 for _, tt := range tests { 72 tt := tt // Re-initializing variable so it is not changed while executing the closure below 73 t.Run(tt.name, func(t *testing.T) { 74 t.Parallel() 75 76 err := PathIsUnderCurrentDirectory(tt.path) 77 if (err == nil && tt.expected != nil) || 78 (err != nil && tt.expected == nil) { 79 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 80 } 81 82 if err != nil && !errors.Is(err, tt.expected) { 83 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 84 } 85 }) 86 } 87 } 88 89 func Test_VerifyAttestationPath(t *testing.T) { 90 t.Parallel() 91 92 tests := []struct { 93 expected error 94 name string 95 path string 96 }{ 97 { 98 name: "valid file", 99 path: "./path/to/valid.intoto.jsonl", 100 expected: nil, 101 }, 102 { 103 name: "invalid path", 104 path: "../some/invalid/valid.intoto.jsonl", 105 expected: ErrInvalidPath, 106 }, 107 { 108 name: "invalid extension", 109 path: "some/file.ntoto.jsonl", 110 expected: ErrInvalidPath, 111 }, 112 { 113 name: "invalid not exntension", 114 path: "some/file.intoto.jsonl.", 115 expected: ErrInvalidPath, 116 }, 117 { 118 name: "invalid folder exntension", 119 path: "file.intoto.jsonl/file", 120 expected: ErrInvalidPath, 121 }, 122 } 123 for _, tt := range tests { 124 tt := tt // Re-initializing variable so it is not changed while executing the closure below 125 t.Run(tt.name, func(t *testing.T) { 126 t.Parallel() 127 128 err := VerifyAttestationPath(tt.path) 129 if (err == nil && tt.expected != nil) || 130 (err != nil && tt.expected == nil) { 131 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 132 } 133 134 if err != nil && !errors.Is(err, tt.expected) { 135 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 136 } 137 }) 138 } 139 } 140 141 func tempWD() (func() error, error) { 142 // Set up a temporary working directory for the test. 143 cwd, err := os.Getwd() 144 if err != nil { 145 return nil, err 146 } 147 tempwd, err := os.MkdirTemp("", "slsa-github-generator-tests") 148 if err != nil { 149 return nil, err 150 } 151 if err := os.Chdir(tempwd); err != nil { 152 return nil, err 153 } 154 return func() error { 155 if err := os.RemoveAll(tempwd); err != nil { 156 return err 157 } 158 return os.Chdir(cwd) 159 }, nil 160 } 161 162 func Test_CreateNewFileUnderCurrentDirectory(t *testing.T) { 163 tests := []struct { 164 expected error 165 name string 166 path string 167 existingPath bool 168 }{ 169 { 170 name: "valid file cannot create", 171 path: "./path/to/validfile", 172 expected: ErrInvalidPath, 173 }, 174 { 175 name: "invalid path", 176 path: "../some/invalid/file", 177 expected: ErrInvalidPath, 178 }, 179 { 180 name: "existing file", 181 path: "existing_file", 182 existingPath: true, 183 expected: ErrInvalidPath, 184 }, 185 { 186 name: "new file", 187 path: "new_file", 188 }, 189 { 190 name: "new file in sub-directory", 191 path: "dir/new_file", 192 expected: ErrInvalidPath, 193 }, 194 } 195 for _, tt := range tests { 196 tt := tt // Re-initializing variable so it is not changed while executing the closure below 197 t.Run(tt.name, func(t *testing.T) { 198 cleanup, err := tempWD() 199 if err != nil { 200 t.Fatal(err) 201 } 202 defer func() { 203 if err := cleanup(); err != nil { 204 t.Fatalf("unexpected error: %v", err) 205 } 206 }() 207 208 if tt.existingPath { 209 if _, err := CreateNewFileUnderCurrentDirectory(tt.path, os.O_WRONLY); err != nil { 210 t.Fatalf("unexpected error: %v", err) 211 } 212 } 213 214 _, err = CreateNewFileUnderCurrentDirectory(tt.path, os.O_WRONLY) 215 if (err == nil && tt.expected != nil) || 216 (err != nil && tt.expected == nil) { 217 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 218 } 219 220 if err != nil && !errors.Is(err, tt.expected) { 221 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 222 } 223 }) 224 } 225 } 226 227 func Test_PathIsUnderDirectory(t *testing.T) { 228 tests := []struct { 229 expected error 230 name string 231 path string 232 dir string 233 }{ 234 { 235 name: "valid same path", 236 path: "./", 237 dir: "./", 238 expected: nil, 239 }, 240 { 241 name: "valid path no slash", 242 path: "./some/valid/path", 243 dir: ".", 244 expected: nil, 245 }, 246 { 247 name: "valid path with slash", 248 path: "./some/valid/path/", 249 dir: ".", 250 expected: nil, 251 }, 252 { 253 name: "valid path with no dot", 254 path: "some/valid/path/", 255 dir: "some/valid/", 256 expected: nil, 257 }, 258 { 259 name: "some valid path", 260 path: "../utils/some/valid/path", 261 dir: "../utils", 262 }, 263 { 264 name: "parent invalid path", 265 path: "../invalid/path", 266 dir: ".", 267 expected: ErrInvalidPath, 268 }, 269 { 270 name: "some valid fullpath", 271 path: "/some/invalid/fullpath", 272 dir: "/some", 273 }, 274 } 275 for _, tt := range tests { 276 tt := tt // Re-initializing variable so it is not changed while executing the closure below 277 t.Run(tt.name, func(t *testing.T) { 278 t.Parallel() 279 280 wd, err := os.Getwd() 281 if err != nil { 282 t.Fatal(err) 283 } 284 d, err := filepath.Abs(filepath.Join(wd, tt.dir)) 285 if err != nil { 286 t.Fatal(err) 287 } 288 err = PathIsUnderDirectory(tt.path, d) 289 if (err == nil && tt.expected != nil) || 290 (err != nil && tt.expected == nil) { 291 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 292 } 293 294 if err != nil && !errors.Is(err, tt.expected) { 295 t.Fatalf("unexpected error: %v", cmp.Diff(err, tt.expected, cmpopts.EquateErrors())) 296 } 297 }) 298 } 299 }