github.com/pkalwak/bagins@v0.0.0-20210317172317-694ac5ce2f54/bag_test.go (about) 1 package bagins_test 2 3 import ( 4 // "fmt" 5 "github.com/pkalwak/bagins" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "testing" 10 ) 11 12 const ( 13 FIXSTRING string = "The quick brown fox jumps over the lazy dog." 14 FIXVALUE string = "e4d909c290d0fb1ca068ffaddf22cbd0" // md5 of string above 15 ) 16 17 func setupTestBag(bagName string) (*bagins.Bag, error) { 18 bag, err := bagins.NewBag(os.TempDir(), bagName, []string{"md5"}, false) 19 if err != nil { 20 return nil, err 21 } 22 return bag, nil 23 } 24 25 // Setups up a bag with some custom tag files. 26 func setupCustomBag(bagName string) (*bagins.Bag, error) { 27 bag, err := bagins.NewBag(os.TempDir(), bagName, []string{"md5", "sha256"}, true) 28 if err != nil { 29 return nil, err 30 } 31 bag.AddTagfile("bag-info.txt") 32 bagInfo, _ := bag.TagFile("bag-info.txt") 33 bagInfo.Data.SetFields([]bagins.TagField{ 34 *bagins.NewTagField("Source-Organization", "APTrust"), 35 *bagins.NewTagField("Bagging-Date", "2016-06-01"), 36 *bagins.NewTagField("Bag-Count", "1"), 37 *bagins.NewTagField("Internal-Sender-Description", "This is a test bag with no content."), 38 *bagins.NewTagField("Internal-Sender-Identification", "Bag XYZ"), 39 }) 40 bag.AddTagfile("aptrust-info.txt") 41 aptrustInfo, _ := bag.TagFile("aptrust-info.txt") 42 aptrustInfo.Data.SetFields([]bagins.TagField{ 43 *bagins.NewTagField("Title", "APTrust Generic Test Bag"), 44 *bagins.NewTagField("Rights", "Consortia"), 45 }) 46 errors := bag.Save() 47 if errors != nil && len(errors) > 0 { 48 return nil, errors[0] 49 } 50 return bag, nil 51 } 52 53 // Setups up a bag with custom tag files, a custom tag directory, 54 // and a tag manifest. 55 func setupTagfileBag(bagName string) (*bagins.Bag, error) { 56 bag, err := setupCustomBag(bagName) 57 if err != nil { 58 return nil, err 59 } 60 61 // Tag file in top-level directory 62 bag.AddTagfile("laser-tag.txt") 63 customTagFile1, _ := bag.TagFile("laser-tag.txt") 64 customTagFile1.Data.SetFields([]bagins.TagField{ 65 *bagins.NewTagField("tic", "tac"), 66 *bagins.NewTagField("tick", "tock"), 67 }) 68 69 // Tag files in custom directory 70 bag.AddTagfile("custom-tags/player-stats.txt") 71 customTagFile2, _ := bag.TagFile("custom-tags/player-stats.txt") 72 customTagFile2.Data.SetFields([]bagins.TagField{ 73 *bagins.NewTagField("Batting-Average", ".340"), 74 *bagins.NewTagField("What-Time-Is-It", "2016-06-01T12:00:00Z"), 75 *bagins.NewTagField("ERA", "1.63"), 76 *bagins.NewTagField("Bats", "Left"), 77 *bagins.NewTagField("Throws", "Right"), 78 }) 79 bag.AddTagfile("custom-tags/tv-schedule.txt") 80 customTagFile3, _ := bag.TagFile("custom-tags/tv-schedule.txt") 81 customTagFile3.Data.SetFields([]bagins.TagField{ 82 *bagins.NewTagField("3:00PM", "House Party"), 83 *bagins.NewTagField("4:00PM", "Dexter"), 84 }) 85 86 errors := bag.Save() 87 if errors != nil && len(errors) > 0 { 88 return nil, errors[0] 89 } 90 return bag, nil 91 } 92 93 func TestNewBag(t *testing.T) { 94 95 // It should raise an error if the destination dir does not exist. 96 badLocation := filepath.Join(os.TempDir(), "/GOTESTNOT_EXISTs/") 97 _, err := bagins.NewBag(badLocation, "_GOFAILBAG_", []string{"md5"}, false) 98 if err == nil { 99 t.Error("NewBag function does not recognize when a directory does not exist!") 100 } 101 102 // It should raise an error if the bag already exists. 103 os.MkdirAll(filepath.Join(badLocation, "_GOFAILBAG_"), 0766) 104 defer os.RemoveAll(badLocation) 105 106 _, err = bagins.NewBag(badLocation, "_GOFAILBAG_", []string{"md5"}, false) 107 if err == nil { 108 t.Error("Error not thrown when bag already exists as expected.") 109 } 110 111 // It should create a bag without any errors. 112 bagName := "_GOTEST_NEWBAG_" 113 bag, err := setupTestBag("_GOTEST_NEWBAG_") 114 defer os.RemoveAll(bag.Path()) 115 116 // It should find all of the following files and directories. 117 if _, err = os.Stat(filepath.Join(os.TempDir(), bagName)); os.IsNotExist(err) { 118 t.Error("Bag directory does not exist!") 119 } 120 if data, err := os.Stat(filepath.Join(os.TempDir(), bagName, "data")); os.IsNotExist(err) || !data.IsDir() { 121 t.Error("Data directory does not exist or is not a directory!") 122 } 123 if _, err = os.Stat(filepath.Join(bag.Path(), "bagit.txt")); os.IsNotExist(err) { 124 bi, err := bag.BagInfo() 125 if err != nil { 126 t.Error(err) 127 } 128 t.Errorf("bagit.txt does not exist! %s", bi.Name()) 129 } 130 if _, err = os.Stat(filepath.Join(os.TempDir(), bagName, "manifest-md5.txt")); os.IsNotExist(err) { 131 t.Error("manifest-md5.txt does not exist!") 132 } 133 } 134 135 func TestReadBag(t *testing.T) { 136 137 // It should return an error when passed a path that doesn't exist. 138 badPath := "/thispath/isbad" 139 if _, err := bagins.ReadBag(badPath, []string{}); err == nil { 140 t.Errorf("Path %s not detected as bad as expected.", badPath) 141 } 142 143 // It should return an error if it isn't passed a path to a directory. 144 fi, _ := ioutil.TempFile("", "TEST_GO_READBAG_") 145 fi.WriteString("Test file please delete.") 146 fi.Close() 147 defer os.Remove(fi.Name()) 148 149 if _, err := bagins.ReadBag(fi.Name(), []string{}); err == nil { 150 t.Errorf("Readbag should thrown an error when trying to open a file: %s", fi.Name()) 151 } 152 153 // It should return an error if the directory does not contain a data subdirectory. 154 pDir, _ := ioutil.TempDir("", "_GOTEST_ReadBag_Payload_") 155 defer os.RemoveAll(pDir) 156 157 if _, err := bagins.ReadBag(pDir, []string{}); err == nil { 158 t.Errorf("Not returning expected error when directory has no data subdirectory for %s", pDir) 159 } 160 161 os.Mkdir(filepath.Join(pDir, "data"), os.ModePerm) // Set up data directory for later tests. 162 163 // It should return an error if there is no manifest file. 164 if _, err := bagins.ReadBag(pDir, []string{}); err == nil { 165 t.Errorf("Not returning expected error when no manifest file is present in %s", pDir) 166 } 167 168 // It should return an error if it has a bad manifest name. 169 ioutil.WriteFile(filepath.Join(pDir, "manifest-sha404.txt"), []byte{}, os.ModePerm) 170 if _, err := bagins.ReadBag(pDir, []string{}); err == nil { 171 t.Errorf("Not returning expected error when a bad manifest filename is only option %s", pDir) 172 } 173 os.Remove(filepath.Join(pDir, "manifest-sha404.txt")) 174 175 // It should return a bag if a valid manifest and data directory exist. 176 ioutil.WriteFile(filepath.Join(pDir, "manifest-sha256.txt"), []byte{}, os.ModePerm) 177 if _, err := bagins.ReadBag(pDir, []string{}); err != nil { 178 t.Errorf("Unexpected error when trying to read raw bag with valid data and manifest: %s", err) 179 } 180 181 // It should read and return a valid bag object reading with a baginfo.txt tagfile. 182 bagName := "__GO_READBAG_TEST__" 183 bagPath := filepath.Join(os.TempDir(), bagName) 184 tb, err := setupTestBag(bagName) 185 defer os.RemoveAll(bagPath) 186 if err != nil { 187 t.Errorf("%s", err) 188 } 189 tb.Save() 190 191 testBag, err := bagins.ReadBag(bagPath, []string{"bagit.txt"}) 192 if err != nil { 193 t.Errorf("Unexpected error reading test bag: %s", err) 194 } 195 baginfo, err := testBag.TagFile("bagit.txt") 196 if err != nil { 197 t.Errorf("Unexpected error reading bagit.txt file: %s", err) 198 } 199 if baginfo == nil { 200 t.Errorf("Baginfo unexpectedly nil.") 201 } 202 } 203 204 func TestReadCustomBag(t *testing.T) { 205 // Setup File to test. 206 fi, _ := ioutil.TempFile("", "TEST_READ_CUSTOM_BAG_FILE.txt") 207 fi.WriteString(FIXSTRING) 208 fi.Close() 209 defer os.Remove(fi.Name()) 210 211 // Setup Custom Bag 212 bagName := "__GO_TEST_READ_CUSTOM_BAG__" 213 bagPath := filepath.Join(os.TempDir(), bagName) 214 defer os.RemoveAll(bagPath) 215 bag, err := setupCustomBag(bagName) 216 if err != nil { 217 t.Errorf("Unexpected error setting up custom bag: %s", err) 218 } 219 bag.AddFile(fi.Name(), fi.Name()) 220 bag.Save() 221 defer os.RemoveAll(bagPath) 222 223 rBag, err := bagins.ReadBag(bag.Path(), []string{"bag-info.txt", "aptrust-info.txt"}) 224 if err != nil { 225 t.Errorf("Unexpected error reading custom bag: %s", err) 226 } 227 228 bagInfo, err := rBag.TagFile("bag-info.txt") 229 if err != nil { 230 t.Errorf("Error finding bag-info.txt tag file: %s", err) 231 } 232 if len(bagInfo.Data.Fields()) != 5 { 233 t.Errorf("Expected 5 fields in bag-info.txt but returned %d", len(bagInfo.Data.Fields())) 234 } 235 236 aptrustInfo, err := rBag.TagFile("aptrust-info.txt") 237 if err != nil { 238 t.Errorf("Error finding aptrust-info.txt tag file: %s", err) 239 } 240 if len(aptrustInfo.Data.Fields()) != 2 { 241 t.Errorf("Expected 2 fields in aptrust-info.txt but returned %d", len(aptrustInfo.Data.Fields())) 242 } 243 244 // Check payload manifests 245 payloadManifests := rBag.GetManifests(bagins.PayloadManifest) 246 if len(payloadManifests) != 2 { 247 t.Errorf("Expected 2 payload manifests, got %d", len(payloadManifests)) 248 } else { 249 if payloadManifests[0].Algorithm() != "md5" { 250 t.Errorf("Expected first manifest to be md5, got %s", payloadManifests[0].Algorithm()) 251 } 252 // Payload md5 manifest should have one entry 253 if len(payloadManifests[0].Data) != 1 { 254 t.Errorf("Payload manifest should have one entry, found %s", len(payloadManifests[0].Data)) 255 } 256 for key, value := range payloadManifests[0].Data { 257 dataFilePath := filepath.Join("data", fi.Name()) 258 if key != dataFilePath { 259 t.Errorf("Missing expected manifest entry for %s. Got %s", dataFilePath, key) 260 } 261 if value != "e4d909c290d0fb1ca068ffaddf22cbd0" { 262 t.Errorf("Incorrect md5 checksum. Got %s", value) 263 } 264 } 265 266 if payloadManifests[1].Algorithm() != "sha256" { 267 t.Errorf("Expected first manifest to be sha256, got %s", payloadManifests[1].Algorithm()) 268 } 269 // Payload sha256 manifest should have one entry 270 if len(payloadManifests[1].Data) != 1 { 271 t.Errorf("Payload manifest should have one entry, found %s", len(payloadManifests[1].Data)) 272 } 273 for key, value := range payloadManifests[1].Data { 274 dataFilePath := filepath.Join("data", fi.Name()) 275 if key != dataFilePath { 276 t.Errorf("Missing expected manifest entry for %s. Got %s", dataFilePath, key) 277 } 278 if value != "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c" { 279 t.Errorf("Incorrect md5 checksum. Got %s", value) 280 } 281 } 282 } 283 } 284 285 func TestReadTagFileBag(t *testing.T) { 286 // Setup File to test. 287 testFileName := "TEST_READ_TAGFILE_BAG_FILE.txt" 288 fi, _ := ioutil.TempFile("", testFileName) 289 fi.WriteString(FIXSTRING) 290 fi.Close() 291 defer os.Remove(fi.Name()) 292 293 // Setup bag with custom tag files 294 bagName := "__GO_TEST_READ_TAGFILE_BAG__" 295 bagPath := filepath.Join(os.TempDir(), bagName) 296 defer os.RemoveAll(bagPath) 297 298 bag, err := setupTagfileBag(bagName) 299 if err != nil { 300 t.Errorf("Unexpected error setting up tagfile bag: %s", err) 301 } 302 bag.AddFile(fi.Name(), testFileName) 303 bag.Save() 304 305 rBag, err := bagins.ReadBag(bag.Path(), []string{"bagit.txt", "bag-info.txt", "aptrust-info.txt"}) 306 if err != nil { 307 t.Errorf("Unexpected error reading custom bag: %s", err) 308 } 309 310 bagInfo, err := rBag.TagFile("bag-info.txt") 311 if err != nil { 312 t.Errorf("Error finding bag-info.txt tag file: %s", err) 313 } 314 if len(bagInfo.Data.Fields()) != 5 { 315 t.Errorf("Expected 5 fields in bag-info.txt but returned %d", len(bagInfo.Data.Fields())) 316 } 317 318 aptrustInfo, err := rBag.TagFile("aptrust-info.txt") 319 if err != nil { 320 t.Errorf("Error finding aptrust-info.txt tag file: %s", err) 321 } 322 if len(aptrustInfo.Data.Fields()) != 2 { 323 t.Errorf("Expected 2 fields in aptrust-info.txt but returned %d", len(aptrustInfo.Data.Fields())) 324 } 325 326 // Check payload manifests 327 payloadManifests := rBag.GetManifests(bagins.PayloadManifest) 328 if len(payloadManifests) != 2 { 329 t.Errorf("Expected 2 payload manifests, got %d", len(payloadManifests)) 330 } else { 331 if payloadManifests[0].Algorithm() != "md5" { 332 t.Errorf("Expected first manifest to be md5, got %s", payloadManifests[0].Algorithm()) 333 } 334 // Payload md5 manifest should have one entry 335 if len(payloadManifests[0].Data) != 1 { 336 t.Errorf("Payload manifest should have one entry, found %s", len(payloadManifests[0].Data)) 337 } 338 for key, value := range payloadManifests[0].Data { 339 dataFilePath := filepath.Join("data", testFileName) 340 if key != dataFilePath { 341 t.Errorf("Missing expected manifest entry for %s. Got %s", dataFilePath, key) 342 } 343 if value != "e4d909c290d0fb1ca068ffaddf22cbd0" { 344 t.Errorf("Incorrect md5 checksum. Got %s", value) 345 } 346 } 347 348 if payloadManifests[1].Algorithm() != "sha256" { 349 t.Errorf("Expected first manifest to be sha256, got %s", payloadManifests[1].Algorithm()) 350 } 351 // Payload sha256 manifest should have one entry 352 if len(payloadManifests[1].Data) != 1 { 353 t.Errorf("Payload manifest should have one entry, found %s", len(payloadManifests[1].Data)) 354 } 355 for key, value := range payloadManifests[1].Data { 356 dataFilePath := filepath.Join("data", testFileName) 357 if key != dataFilePath { 358 t.Errorf("Missing expected manifest entry for %s. Got %s", dataFilePath, key) 359 } 360 if value != "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c" { 361 t.Errorf("Incorrect md5 checksum. Got %s", value) 362 } 363 } 364 } 365 366 // Check that tag files exist on disk 367 aptrustInfoFile := "aptrust-info.txt" 368 bagInfoFile := "bag-info.txt" 369 bagItFile := "bagit.txt" 370 laserTagFile := "laser-tag.txt" 371 playerStatsFile := filepath.Join("custom-tags", "player-stats.txt") 372 tvScheduleFile := filepath.Join("custom-tags", "tv-schedule.txt") 373 manifestMd5 := "manifest-md5.txt" 374 manifestSha256 := "manifest-sha256.txt" 375 376 tagFiles := []string{aptrustInfoFile, bagInfoFile, bagItFile, 377 laserTagFile, playerStatsFile, tvScheduleFile} 378 for _, tf := range tagFiles { 379 absPath := filepath.Join(bagPath, tf) 380 _, err = os.Stat(absPath) 381 if err != nil && os.IsNotExist(err) { 382 t.Errorf("Tag file is not written to disk at %s", tf) 383 } 384 } 385 386 // Make sure the bag knows they're there too 387 files, err := rBag.ListFiles() 388 if err != nil { 389 t.Errorf("ListFiles() returned error %v", err) 390 } 391 expectedFiles := []string{ 392 "aptrust-info.txt", 393 "bag-info.txt", 394 "bagit.txt", 395 "custom-tags/player-stats.txt", 396 "custom-tags/tv-schedule.txt", 397 "data/TEST_READ_TAGFILE_BAG_FILE.txt", 398 "laser-tag.txt", 399 "manifest-md5.txt", 400 "manifest-sha256.txt", 401 "tagmanifest-md5.txt", 402 "tagmanifest-sha256.txt", 403 } 404 for _, expectedFile := range expectedFiles { 405 if !sliceContains(files, expectedFile) { 406 t.Errorf("ListFiles did not return file %s", expectedFile) 407 } 408 } 409 410 // Make sure the bag knows about the parsed tag files 411 expectedParsedFiles := []string{"bagit.txt", "bag-info.txt", "aptrust-info.txt"} 412 parsedTagFiles := rBag.ListTagFiles() 413 if len(parsedTagFiles) != len(expectedParsedFiles) { 414 t.Errorf("Expected %d parsed tag files, got %d", 415 len(parsedTagFiles), len(expectedParsedFiles)) 416 } 417 418 for _, expected := range expectedParsedFiles { 419 if !sliceContains(parsedTagFiles, expected) { 420 t.Errorf("ListTagFiles() did not return file %s", expected) 421 } 422 } 423 424 // Make sure the bag knows about unparsed tag files 425 expectedUnparsed := []string{ 426 "custom-tags/player-stats.txt", 427 "custom-tags/tv-schedule.txt", 428 "laser-tag.txt"} 429 unparsedTagFiles, err := rBag.UnparsedTagFiles() 430 if err != nil { 431 t.Errorf("UnparsedTagFiles() returned unexpected error: %v", err) 432 } 433 434 if len(unparsedTagFiles) != len(expectedUnparsed) { 435 t.Errorf("Expected %d parsed tag files, got %d", 436 len(unparsedTagFiles), len(expectedUnparsed)) 437 } 438 439 for _, expected := range expectedUnparsed { 440 if !sliceContains(unparsedTagFiles, expected) { 441 t.Errorf("UnparsedTagFiles() did not return file %s", expected) 442 } 443 } 444 445 // Check tag manifests 446 tagManifests := rBag.GetManifests(bagins.TagManifest) 447 if len(tagManifests) != 2 { 448 t.Errorf("Expected 2 tag manifests, got %d", len(tagManifests)) 449 } else { 450 if tagManifests[0].Algorithm() != "md5" { 451 t.Errorf("Expected first manifest to be md5, got %s", tagManifests[0].Algorithm()) 452 } 453 // Tag md5 manifest should have six entries 454 if len(tagManifests[0].Data) != 8 { 455 t.Errorf("Tag manifest should have 8 entries, found %d", len(tagManifests[0].Data)) 456 } 457 458 // Check the fixity values 459 md5Entries := make(map[string]string, 6) 460 md5Entries[aptrustInfoFile] = "6dd711392d4661322acc469a30565f68" 461 md5Entries[bagInfoFile] = "88190858fd93609ae51ca1f06ee575f1" 462 md5Entries[bagItFile] = "ada799b7e0f1b7a1dc86d4e99df4b1f4" 463 md5Entries[laserTagFile] = "29251712228b36927c43157fe5808552" 464 md5Entries[playerStatsFile] = "dfa872f6da2af8087bea5f7ab1dbc1fa" 465 md5Entries[tvScheduleFile] = "118df3be000eae34d6e6dbf7f56c649b" 466 md5Entries[manifestMd5] = "4c5a8c217cf51fb419e425ddc2f433ee" 467 md5Entries[manifestSha256] = "edbc9b8dabe4c894d22cc42d5268867b" 468 469 for key, expectedValue := range md5Entries { 470 actualValue := tagManifests[0].Data[key] 471 if actualValue != expectedValue { 472 t.Errorf("For tag file %s, expected md5 %s, but got %s", 473 key, expectedValue, actualValue) 474 } 475 } 476 477 if tagManifests[1].Algorithm() != "sha256" { 478 t.Errorf("Expected first manifest to be sha256, got %s", tagManifests[1].Algorithm()) 479 } 480 // Tag sha256 manifest should have 8 entries (2 are for payload manifests) 481 if len(tagManifests[1].Data) != 8 { 482 t.Errorf("Tag manifest should have 8 entries, found %d", len(tagManifests[1].Data)) 483 } 484 485 // Check fixity values 486 // Will these checksums break on Windows, where end-of-line is CRLF? 487 sha256Entries := make(map[string]string, 6) 488 sha256Entries[aptrustInfoFile] = 489 "ffe2ab04b87db85886fcfd013c9f09e094b636ca233cd0cbbd1ea300e7a5352c" 490 sha256Entries[bagInfoFile] = 491 "f0ce035c2ee789a7f8821d6f174a75619c575eea0311c47d03149807d252804d" 492 sha256Entries[bagItFile] = 493 "49b477e8662d591f49fce44ca5fc7bfe76c5a71f69c85c8d91952a538393e5f4" 494 sha256Entries[laserTagFile] = 495 "163be000df169eafd84fa0cef6028a4711e53bd3abf9e8c54603035bb92bda95" 496 sha256Entries[playerStatsFile] = 497 "83137fc6d88212250153bd713954da1d1c5a69c57a55ff97cac07ca6db7ec34d" 498 sha256Entries[tvScheduleFile] = 499 "fbf223502fe7f470363346283620401d04e77fe43a9a74faa682eebe28417e7c" 500 sha256Entries[manifestMd5] = 501 "9aab27bb0d2d75d7ac2c26908e2ca85e7121f106445318f7def024f4b520bec2" 502 sha256Entries[manifestSha256] = 503 "2a9e5d86070459a652fdc2ce13f5358ede42b10a3e0580e149b0d3df938ffe30" 504 505 for key, expectedValue := range sha256Entries { 506 actualValue := tagManifests[1].Data[key] 507 if actualValue != expectedValue { 508 t.Errorf("For tag file %s, expected sha256 %s, but got %s", 509 key, expectedValue, actualValue) 510 } 511 } 512 } 513 } 514 515 // It should place an appropriate file in the data directory and add the fixity to the manifest. 516 func TestAddFile(t *testing.T) { 517 // Setup the test file to add for the test. 518 fi, _ := ioutil.TempFile("", "TEST_GO_ADDFILE_") 519 fi.WriteString("Test the checksum") 520 fi.Close() 521 defer os.Remove(fi.Name()) 522 523 // Setup the Test Bag 524 bag, _ := setupTestBag("_GOTEST_BAG_ADDFILE_") 525 defer os.RemoveAll(bag.Path()) 526 527 // It should return an error when trying to add a file that doesn't exist. 528 if err := bag.AddFile("idontexist.txt", "idontexist.txt"); err == nil { 529 t.Errorf("Adding a nonexistant file did not generate an error!") 530 } 531 532 // It should add a file to the data directory and generate a fixity value. 533 expFile := "my/nested/dir/mytestfile.txt" 534 if err := bag.AddFile(fi.Name(), expFile); err != nil { 535 t.Error(err) 536 } 537 538 // It should have created the file in the payload directory. 539 _, err := os.Stat(filepath.Join(bag.Path(), "data", expFile)) 540 if err != nil { 541 t.Error("Testing if payload file created:", err) 542 } 543 544 // It should have calulated the fixity and put it in the manifest. 545 if bag.Manifests == nil || len(bag.Manifests) == 0 { 546 t.Error("Bag manifest is missing") 547 return 548 } 549 mf := bag.Manifests[0] 550 expKey := filepath.Join("data", expFile) 551 fx, ok := mf.Data[expKey] 552 if !ok { 553 t.Error("Unable to find entry in manfest: ", expKey) 554 } 555 if len(fx) != 32 { 556 t.Errorf("Expected %d character fixity but returned: %d", 32, len(fx)) 557 } 558 } 559 560 func TestAddCustomTagfile(t *testing.T) { 561 // Setup File to test. 562 fi, _ := ioutil.TempFile("", "TEST_READ_CUSTOM_BAG_FILE.txt") 563 fi.WriteString(FIXSTRING) 564 fi.Close() 565 defer os.Remove(fi.Name()) 566 567 // Setup Custom Bag 568 bagName := "__GO_TEST_ADD_CUSTOM_TAG_FILE__" 569 bagPath := filepath.Join(os.TempDir(), bagName) 570 defer os.RemoveAll(bagPath) 571 bag, err := setupCustomBag(bagName) 572 if err != nil { 573 t.Errorf("Unexpected error setting up custom bag: %s", err) 574 } 575 bag.AddCustomTagfile(fi.Name(), "custom-tags/in_manifest.txt", true) 576 bag.AddCustomTagfile(fi.Name(), "custom-tags/not_in_manifest.txt", false) 577 bag.Save() 578 defer os.RemoveAll(bagPath) 579 580 rBag, err := bagins.ReadBag(bag.Path(), []string{"bag-info.txt", "aptrust-info.txt"}) 581 if err != nil { 582 t.Errorf("Unexpected error reading custom bag: %s", err) 583 } 584 585 files, err := rBag.ListFiles() 586 if err != nil { 587 t.Errorf("Error listing bag files: %v", err) 588 } 589 590 // Make sure the file exists 591 if !sliceContains(files, "custom-tags/in_manifest.txt") { 592 t.Errorf("Custom tag file 'custom-tags/in_manifest.txt' is not in the bag") 593 } 594 if !sliceContains(files, "custom-tags/not_in_manifest.txt") { 595 t.Errorf("Custom tag file 'custom-tags/not_in_manifest.txt' is not in the bag") 596 } 597 598 // First file should be in the tag manifests. Second file should not. 599 tagManifests := rBag.GetManifests(bagins.TagManifest) 600 for _, tagManifest := range tagManifests { 601 if _, exists := tagManifest.Data["custom-tags/in_manifest.txt"]; exists == false { 602 t.Errorf("File 'custom-tags/in_manifest.txt' is missing from tagmanifest-%s.txt", 603 tagManifest.Algorithm()) 604 } 605 if _, exists := tagManifest.Data["custom-tags/not_in_manifest.txt"]; exists == true { 606 t.Errorf("File 'custom-tags/not_in_manifest.txt' is should not have an entry in "+ 607 "tagmanifest-%s.txt, but it does", tagManifest.Algorithm()) 608 } 609 } 610 } 611 612 func TestListTagFiles(t *testing.T) { 613 // Setup Custom Bag 614 bagName := "__GO_TEST_LIST_TAG_FILES__" 615 bagPath := filepath.Join(os.TempDir(), bagName) 616 defer os.RemoveAll(bagPath) 617 bag, err := setupCustomBag(bagName) 618 if err != nil { 619 t.Errorf("Unexpected error setting up custom bag: %s", err) 620 } 621 622 expected := []string{"bagit.txt", "bag-info.txt", "aptrust-info.txt"} 623 if len(bag.ListTagFiles()) != len(expected) { 624 t.Errorf("Expected %d tag files but returned %d", len(expected), len(bag.ListTagFiles())) 625 } 626 for _, name := range expected { 627 if _, err := bag.TagFile(name); err != nil { 628 t.Errorf("Error getting tag file %s: %s", name, err) 629 } 630 } 631 } 632 633 func TestAddDir(t *testing.T) { 634 635 // Setup source files to test 636 srcDir, _ := ioutil.TempDir("", "_GOTEST_PAYLOAD_SRC_") 637 for i := 0; i < 50; i++ { 638 fi, _ := ioutil.TempFile(srcDir, "TEST_GO_ADDFILE_") 639 fi.WriteString(FIXSTRING) 640 fi.Close() 641 } 642 defer os.RemoveAll(srcDir) 643 644 // Setup the test bag 645 bag, err := setupTestBag("_GOTEST_BAG_ADDDIR_") 646 if err != nil { 647 t.Error(err.Error()) 648 return 649 } 650 defer os.RemoveAll(bag.Path()) 651 652 // It should produce no errors 653 if errs := bag.AddDir(srcDir); len(errs) != 0 { 654 t.Error(errs) 655 } 656 657 // It should produce 50 manifest entries 658 if bag.Manifests == nil || len(bag.Manifests) == 0 { 659 t.Error("Bag manifest is missing") 660 return 661 } 662 manifest := bag.Manifests[0] 663 if len(manifest.Data) != 50 { 664 t.Error("Expected 50 manifest entries but returned", len(manifest.Data)) 665 } 666 // It should contain the proper checksums for each file. 667 errs := manifest.RunChecksums() 668 for _, err := range errs { 669 t.Errorf("%s", err) 670 } 671 } 672 673 func TestManifest(t *testing.T) { 674 675 // Setup the test bag 676 bag, _ := setupTestBag("_GOTEST_BAG_MANIFEST_") 677 defer os.RemoveAll(bag.Path()) 678 679 // It should have the expected name and return no error. 680 if bag.Manifests == nil || len(bag.Manifests) == 0 { 681 t.Error("Bag manifest is missing") 682 return 683 } 684 mf := bag.Manifests[0] 685 exp := "manifest-md5.txt" 686 if filepath.Base(mf.Name()) != exp { 687 t.Error("Expected manifest name", exp, "but returned", filepath.Base(mf.Name())) 688 } 689 } 690 691 func TestAddTagFile(t *testing.T) { 692 693 // Setup the test bag 694 bag, _ := setupTestBag("_GOTEST_BAG_ADDTAGFILE_") 695 defer os.RemoveAll(bag.Path()) 696 697 // It should throw an error when a bag tagfilename is passed. 698 badTagName := "customtag/directory/tag" 699 if err := bag.AddTagfile(badTagName); err == nil { 700 t.Error("Did not generate an error when trying to add bag tagname:", badTagName) 701 } 702 703 // It should not throw an error. 704 newTagName := "customtag/directory/tag.txt" 705 if err := bag.AddTagfile(newTagName); err != nil { 706 t.Error(err) 707 } 708 709 // It should be able to lookup the tagfile by name. 710 if _, err := bag.TagFile(newTagName); err != nil { 711 t.Error(err) 712 } 713 714 // Even tagfiles passed as root should be put under the bag. 715 oddTagName := "/lookslikeroot/directory/tag.txt" 716 if err := bag.AddTagfile(oddTagName); err != nil { 717 t.Error(err) 718 } 719 720 // It should be able to lookup the tagfile by name. 721 if _, err := bag.TagFile(oddTagName); err != nil { 722 t.Error(err) 723 } 724 725 // It should find the file inside the bag. 726 if _, err := os.Stat(filepath.Join(bag.Path(), newTagName)); err != nil { 727 t.Error(err) 728 } 729 } 730 731 func TestTagFile(t *testing.T) { 732 733 // Setup the test bag 734 bag, _ := setupTestBag("_GOTEST_BAG_TAGFILE_") 735 defer os.RemoveAll(bag.Path()) 736 737 // It should find the tag file by name 738 testTagName := "new/tag.txt" 739 bag.AddTagfile(testTagName) 740 if _, err := bag.TagFile(testTagName); err != nil { 741 t.Error(err) 742 } 743 744 // It should return an error if asking for a bad tag name. 745 badTagName := "/new/tag.txt" 746 if _, err := bag.TagFile(badTagName); err == nil { 747 t.Error("Bag.TagFile returned results for", badTagName, "when it should not exist.") 748 } 749 } 750 751 func TestPath(t *testing.T) { 752 // Stup the test bag 753 bagName := "_GOTEST_BAG_PATH_" 754 bag, _ := setupTestBag(bagName) 755 defer os.RemoveAll(bag.Path()) 756 757 expPath := filepath.Join(os.TempDir(), bagName) 758 if bag.Path() != expPath { 759 t.Error("Excpected", bag.Path(), "and", expPath, "to be equal!") 760 } 761 } 762 763 func TestSave(t *testing.T) { 764 // Setup test bag 765 bag, _ := setupTestBag("_GOTEST_BAG_CLOSE_") 766 defer os.RemoveAll(bag.Path()) 767 768 // Add some data to the manifest and make sure it writes it on close. 769 bag.Manifests[0].Data["data/fakefile.txt"] = "da909ba395016f2a64b04d706520db6afa74fc95" 770 771 // It should not throw an error. 772 if errs := bag.Save(); len(errs) != 0 { 773 for idx := range errs { 774 t.Error(errs[idx]) 775 } 776 } 777 778 // The manifest file should contain data. 779 content, err := ioutil.ReadFile(bag.Manifests[0].Name()) 780 if err != nil { 781 t.Error(err) 782 } 783 exp := 59 // Length of values entered above and newline. 784 if len(content) != 59 { 785 t.Error("Expected ", exp, "but found", len(content), "characters written") 786 } 787 788 // Add some tagfile data to make sure it writes it on close. 789 tfName := "extratagfile.txt" 790 bag.AddTagfile("extratagfile.txt") 791 tf, _ := bag.TagFile(tfName) 792 tf.Data.AddField(*bagins.NewTagField("MyNewField", "This is testdata.")) 793 794 // it should not throw an error. 795 if errs := bag.Save(); len(errs) != 0 { 796 for idx := range errs { 797 t.Error(errs[idx]) 798 } 799 } 800 801 // The TagFile should contain data. 802 content, err = ioutil.ReadFile(tf.Name()) 803 if err != nil { 804 t.Error(err) 805 } 806 exp = 10 // Some length the string needs to be abovel 807 if len(content) < exp { 808 t.Error("Didn't find data in tagfile", tfName, "as expected!") 809 } 810 } 811 812 func TestListFiles(t *testing.T) { 813 814 // Setup the test bag. 815 bag, _ := setupTestBag("_GOTEST_BAG_LISTFILES_") 816 defer os.RemoveAll(bag.Path()) 817 818 // Setup the test file to add for the test. 819 fi, _ := os.Create(filepath.Join(bag.Path(), "data", "TEST_GO_DATAFILE.txt")) 820 fi.WriteString("Test the checksum") 821 fi.Close() 822 823 expFiles := make(map[string]bool) 824 expFiles["manifest-md5.txt"] = true 825 expFiles["bagit.txt"] = true 826 expFiles[filepath.Join("data", "TEST_GO_DATAFILE.txt")] = true 827 828 cn, _ := bag.ListFiles() 829 830 for _, fName := range cn { 831 if _, ok := expFiles[fName]; !ok { 832 t.Error("Unexpected file:", fName) 833 } 834 } 835 } 836 837 func sliceContains(list []string, item string) bool { 838 for _, value := range list { 839 if value == item { 840 return true 841 } 842 } 843 return false 844 }