github.com/ubuntu/ubuntu-report@v1.7.4-0.20240410144652-96f37d845fac/pkg/sysmetrics/api_test.go (about) 1 package sysmetrics_test 2 3 import ( 4 "bufio" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/ubuntu/ubuntu-report/internal/helper" 15 "github.com/ubuntu/ubuntu-report/pkg/sysmetrics" 16 ) 17 18 func TestCollect(t *testing.T) { 19 t.Parallel() 20 21 data, err := sysmetrics.Collect() 22 23 if err != nil { 24 t.Fatal("we didn't expect an error and got one", err) 25 } 26 27 if !strings.Contains(string(data), sysmetrics.ExpectedReportItem) { 28 t.Errorf("we expected at least %s in output, got: '%s", sysmetrics.ExpectedReportItem, string(data)) 29 } 30 } 31 32 func TestSendReport(t *testing.T) { 33 // we change current path and env variable: not parallelizable tests 34 helper.SkipIfShort(t) 35 36 testCases := []struct { 37 name string 38 alwaysReport bool 39 40 shouldHitServer bool 41 wantErr bool 42 }{ 43 {"regular send", false, true, false}, 44 } 45 for _, tc := range testCases { 46 tc := tc // capture range variable for parallel execution 47 t.Run(tc.name, func(t *testing.T) { 48 a := helper.Asserter{T: t} 49 50 out, tearDown := helper.TempDir(t) 51 defer tearDown() 52 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 53 out = filepath.Join(out, "ubuntu-report") 54 // we don't really care where we hit for this API integration test, internal ones test it 55 // and we don't really control /etc/os-release version and id. 56 // Same for report file 57 serverHit := false 58 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 59 serverHit = true 60 })) 61 defer ts.Close() 62 63 err := sysmetrics.SendReport([]byte(fmt.Sprintf(`{ %s: "18.04" }`, sysmetrics.ExpectedReportItem)), 64 tc.alwaysReport, ts.URL) 65 66 a.CheckWantedErr(err, tc.wantErr) 67 a.Equal(serverHit, tc.shouldHitServer) 68 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 69 data, err := ioutil.ReadFile(p) 70 if err != nil { 71 t.Fatalf("couldn't open report file %s", out) 72 } 73 d := string(data) 74 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 75 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.ExpectedReportItem, d) 76 } 77 }) 78 } 79 } 80 func TestSendDecline(t *testing.T) { 81 // we change current path and env variable: not parallelizable tests 82 helper.SkipIfShort(t) 83 84 testCases := []struct { 85 name string 86 alwaysReport bool 87 88 shouldHitServer bool 89 wantErr bool 90 }{ 91 {"regular send opt-out", false, true, false}, 92 } 93 for _, tc := range testCases { 94 tc := tc // capture range variable for parallel execution 95 t.Run(tc.name, func(t *testing.T) { 96 a := helper.Asserter{T: t} 97 98 out, tearDown := helper.TempDir(t) 99 defer tearDown() 100 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 101 out = filepath.Join(out, "ubuntu-report") 102 // we don't really care where we hit for this API integration test, internal ones test it 103 // and we don't really control /etc/os-release version and id. 104 // Same for report file 105 serverHit := false 106 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 107 serverHit = true 108 })) 109 defer ts.Close() 110 111 err := sysmetrics.SendDecline(tc.alwaysReport, ts.URL) 112 113 if err != nil { 114 t.Fatal("we didn't expect getting an error, got:", err) 115 } 116 117 a.Equal(serverHit, tc.shouldHitServer) 118 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 119 data, err := ioutil.ReadFile(p) 120 if err != nil { 121 t.Fatalf("couldn't open report file %s", out) 122 } 123 d := string(data) 124 if !strings.Contains(d, sysmetrics.OptOutJSON) { 125 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.OptOutJSON, d) 126 } 127 }) 128 } 129 } 130 131 func TestSendReportTwice(t *testing.T) { 132 // we change current path and env variable: not parallelizable tests 133 helper.SkipIfShort(t) 134 135 testCases := []struct { 136 name string 137 alwaysReport bool 138 139 wantErr bool 140 }{ 141 {"fail report twice", false, true}, 142 {"forcing report twice", true, false}, 143 } 144 for _, tc := range testCases { 145 tc := tc // capture range variable for parallel execution 146 t.Run(tc.name, func(t *testing.T) { 147 a := helper.Asserter{T: t} 148 149 out, tearDown := helper.TempDir(t) 150 defer tearDown() 151 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 152 out = filepath.Join(out, "ubuntu-report") 153 // we don't really care where we hit for this API integration test, internal ones test it 154 // and we don't really control /etc/os-release version and id. 155 // Same for report file 156 serverHit := false 157 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 158 serverHit = true 159 })) 160 defer ts.Close() 161 162 // first call 163 err := sysmetrics.SendReport([]byte(fmt.Sprintf(`{ %s: "18.04" }`, sysmetrics.ExpectedReportItem)), 164 tc.alwaysReport, ts.URL) 165 if err != nil { 166 t.Fatal("we didn't expect getting an error, got:", err) 167 } 168 a.Equal(serverHit, true) 169 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 170 data, err := ioutil.ReadFile(p) 171 if err != nil { 172 t.Fatalf("couldn't open report file %s", out) 173 } 174 d := string(data) 175 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 176 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.ExpectedReportItem, d) 177 } 178 179 // scratch data file 180 if err != ioutil.WriteFile(p, []byte(""), 0644) { 181 t.Fatalf("couldn't reset %s: %v", p, err) 182 } 183 184 // second call, reset server 185 serverHit = false 186 err = sysmetrics.SendReport([]byte(fmt.Sprintf(`{ %s: "18.04" }`, sysmetrics.ExpectedReportItem)), 187 tc.alwaysReport, ts.URL) 188 a.CheckWantedErr(err, tc.wantErr) 189 190 a.Equal(serverHit, tc.alwaysReport) 191 // reread the same file 192 data, err = ioutil.ReadFile(p) 193 if err != nil { 194 t.Fatalf("couldn't open report file %s", out) 195 } 196 d = string(data) 197 switch tc.alwaysReport { 198 case true: 199 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 200 t.Errorf("we expected to find %s in second report file, got: %s", sysmetrics.ExpectedReportItem, d) 201 } 202 case false: 203 if d != "" { 204 t.Errorf("we expected to have an untouched report file on second report, got: %s", d) 205 } 206 } 207 208 }) 209 } 210 } 211 212 func TestSendDeclineTwice(t *testing.T) { 213 // we change current path and env variable: not parallelizable tests 214 helper.SkipIfShort(t) 215 216 testCases := []struct { 217 name string 218 alwaysReport bool 219 220 wantErr bool 221 }{ 222 {"fail decline twice", false, true}, 223 {"forcing decline twice", true, false}, 224 } 225 for _, tc := range testCases { 226 tc := tc // capture range variable for parallel execution 227 t.Run(tc.name, func(t *testing.T) { 228 a := helper.Asserter{T: t} 229 230 out, tearDown := helper.TempDir(t) 231 defer tearDown() 232 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 233 out = filepath.Join(out, "ubuntu-report") 234 // we don't really care where we hit for this API integration test, internal ones test it 235 // and we don't really control /etc/os-release version and id. 236 // Same for report file 237 serverHit := false 238 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 239 serverHit = true 240 })) 241 defer ts.Close() 242 243 // first call 244 err := sysmetrics.SendDecline(tc.alwaysReport, ts.URL) 245 if err != nil { 246 t.Fatal("we didn't expect getting an error, got:", err) 247 } 248 a.Equal(serverHit, true) 249 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 250 data, err := ioutil.ReadFile(p) 251 if err != nil { 252 t.Fatalf("couldn't open report file %s", out) 253 } 254 d := string(data) 255 if !strings.Contains(d, sysmetrics.OptOutJSON) { 256 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.OptOutJSON, d) 257 } 258 259 // scratch data file 260 if err != ioutil.WriteFile(p, []byte(""), 0644) { 261 t.Fatalf("couldn't reset %s: %v", p, err) 262 } 263 264 // second call, reset server 265 serverHit = false 266 err = sysmetrics.SendDecline(tc.alwaysReport, ts.URL) 267 a.CheckWantedErr(err, tc.wantErr) 268 269 a.Equal(serverHit, tc.alwaysReport) 270 // reread the same file 271 data, err = ioutil.ReadFile(p) 272 if err != nil { 273 t.Fatalf("couldn't open report file %s", out) 274 } 275 d = string(data) 276 switch tc.alwaysReport { 277 case true: 278 if !strings.Contains(d, sysmetrics.OptOutJSON) { 279 t.Errorf("we expected to find %s in second report file, got: %s", sysmetrics.OptOutJSON, d) 280 } 281 case false: 282 if d != "" { 283 t.Errorf("we expected to have an untouched report file on second report, got: %s", d) 284 } 285 } 286 287 }) 288 } 289 } 290 291 func TestNonInteractiveCollectAndSend(t *testing.T) { 292 // we change current path and env variable: not parallelizable tests 293 helper.SkipIfShort(t) 294 295 testCases := []struct { 296 name string 297 r sysmetrics.ReportType 298 alwaysReport bool 299 300 shouldHitServer bool 301 wantErr bool 302 }{ 303 {"regular report auto", sysmetrics.ReportAuto, false, true, false}, 304 {"regular report opt-out", sysmetrics.ReportOptOut, false, true, false}, 305 } 306 for _, tc := range testCases { 307 tc := tc // capture range variable for parallel execution 308 t.Run(tc.name, func(t *testing.T) { 309 a := helper.Asserter{T: t} 310 311 out, tearDown := helper.TempDir(t) 312 defer tearDown() 313 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 314 out = filepath.Join(out, "ubuntu-report") 315 // we don't really care where we hit for this API integration test, internal ones test it 316 // and we don't really control /etc/os-release version and id. 317 // Same for report file 318 serverHit := false 319 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 320 serverHit = true 321 })) 322 defer ts.Close() 323 324 err := sysmetrics.CollectAndSend(tc.r, tc.alwaysReport, ts.URL) 325 326 if err != nil { 327 t.Fatal("we didn't expect getting an error, got:", err) 328 } 329 330 a.Equal(serverHit, tc.shouldHitServer) 331 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 332 data, err := ioutil.ReadFile(p) 333 if err != nil { 334 t.Fatalf("couldn't open report file %s", out) 335 } 336 d := string(data) 337 switch tc.r { 338 case sysmetrics.ReportAuto: 339 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 340 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.ExpectedReportItem, d) 341 } 342 case sysmetrics.ReportOptOut: 343 if !strings.Contains(d, sysmetrics.OptOutJSON) { 344 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.OptOutJSON, d) 345 } 346 } 347 }) 348 } 349 } 350 351 func TestCollectAndSendTwice(t *testing.T) { 352 // we change current path and env variable: not parallelizable tests 353 helper.SkipIfShort(t) 354 355 testCases := []struct { 356 name string 357 alwaysReport bool 358 359 wantErr bool 360 }{ 361 {"fail report twice", false, true}, 362 {"forcing report twice", true, false}, 363 } 364 for _, tc := range testCases { 365 tc := tc // capture range variable for parallel execution 366 t.Run(tc.name, func(t *testing.T) { 367 a := helper.Asserter{T: t} 368 369 out, tearDown := helper.TempDir(t) 370 defer tearDown() 371 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 372 out = filepath.Join(out, "ubuntu-report") 373 // we don't really care where we hit for this API integration test, internal ones test it 374 // and we don't really control /etc/os-release version and id. 375 // Same for report file 376 serverHit := false 377 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 378 serverHit = true 379 })) 380 defer ts.Close() 381 382 // first call 383 err := sysmetrics.CollectAndSend(sysmetrics.ReportAuto, tc.alwaysReport, ts.URL) 384 if err != nil { 385 t.Fatal("we didn't expect getting an error, got:", err) 386 } 387 a.Equal(serverHit, true) 388 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 389 data, err := ioutil.ReadFile(p) 390 if err != nil { 391 t.Fatalf("couldn't open report file %s", out) 392 } 393 d := string(data) 394 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 395 t.Errorf("we expected to find %s in report file, got: %s", sysmetrics.ExpectedReportItem, d) 396 } 397 398 // scratch data file 399 if err != ioutil.WriteFile(p, []byte(""), 0644) { 400 t.Fatalf("couldn't reset %s: %v", p, err) 401 } 402 403 // second call, reset server 404 serverHit = false 405 err = sysmetrics.CollectAndSend(sysmetrics.ReportAuto, tc.alwaysReport, ts.URL) 406 a.CheckWantedErr(err, tc.wantErr) 407 408 a.Equal(serverHit, tc.alwaysReport) 409 // reread the same file 410 data, err = ioutil.ReadFile(p) 411 if err != nil { 412 t.Fatalf("couldn't open report file %s", out) 413 } 414 d = string(data) 415 switch tc.alwaysReport { 416 case true: 417 if !strings.Contains(d, sysmetrics.ExpectedReportItem) { 418 t.Errorf("we expected to find %s in second report file, got: %s", sysmetrics.ExpectedReportItem, d) 419 } 420 case false: 421 if d != "" { 422 t.Errorf("we expected to have an untouched report file on second report, got: %s", d) 423 } 424 } 425 426 }) 427 } 428 } 429 430 func TestInteractiveCollectAndSend(t *testing.T) { 431 // we change current path and env variable: not parallelizable tests 432 helper.SkipIfShort(t) 433 434 testCases := []struct { 435 name string 436 answers []string 437 438 sendOnlyOptOutData bool 439 wantWriteAndUpload bool 440 }{ 441 {"yes", []string{"yes"}, false, true}, 442 {"y", []string{"y"}, false, true}, 443 {"YES", []string{"YES"}, false, true}, 444 {"Y", []string{"Y"}, false, true}, 445 {"no", []string{"no"}, true, true}, 446 {"n", []string{"n"}, true, true}, 447 {"NO", []string{"NO"}, true, true}, 448 {"n", []string{"N"}, true, true}, 449 {"quit", []string{"quit"}, false, false}, 450 {"q", []string{"q"}, false, false}, 451 {"QUIT", []string{"QUIT"}, false, false}, 452 {"Q", []string{"Q"}, false, false}, 453 {"default-quit", []string{""}, false, false}, 454 {"garbage-then-quit", []string{"garbage", "yesgarbage", "nogarbage", "quitgarbage", "Q"}, false, false}, 455 {"ctrl-c-input", []string{"CTRL-C"}, false, false}, 456 } 457 for _, tc := range testCases { 458 tc := tc // capture range variable for parallel execution 459 t.Run(tc.name, func(t *testing.T) { 460 a := helper.Asserter{T: t} 461 462 out, tearDown := helper.TempDir(t) 463 defer tearDown() 464 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 465 out = filepath.Join(out, "ubuntu-report") 466 // we don't really care where we hit for this API integration test, internal ones test it 467 // and we don't really control /etc/os-release version and id. 468 // Same for report file 469 serverHit := false 470 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 471 serverHit = true 472 })) 473 defer ts.Close() 474 475 stdout, tearDown := helper.CaptureStdout(t) 476 defer tearDown() 477 stdin, tearDown := helper.CaptureStdin(t) 478 defer tearDown() 479 480 cmdErrs := helper.RunFunctionWithTimeout(t, func() error { return sysmetrics.CollectAndSend(sysmetrics.ReportInteractive, false, ts.URL) }) 481 482 gotJSONReport := false 483 answerIndex := 0 484 scanner := bufio.NewScanner(stdout) 485 scanner.Split(sysmetrics.ScanLinesOrQuestion) 486 for scanner.Scan() { 487 txt := scanner.Text() 488 // first, we should have a known element 489 if strings.Contains(txt, sysmetrics.ExpectedReportItem) { 490 gotJSONReport = true 491 } 492 if !strings.Contains(txt, "Do you agree to report this?") { 493 continue 494 } 495 a := tc.answers[answerIndex] 496 if a == "CTRL-C" { 497 stdin.Close() 498 break 499 } else { 500 stdin.Write([]byte(tc.answers[answerIndex] + "\n")) 501 } 502 answerIndex = answerIndex + 1 503 // all answers have be provided 504 if answerIndex >= len(tc.answers) { 505 stdin.Close() 506 break 507 } 508 } 509 510 if err := <-cmdErrs; err != nil { 511 t.Fatal("didn't expect to get an error, got:", err) 512 } 513 a.Equal(gotJSONReport, true) 514 a.Equal(serverHit, tc.wantWriteAndUpload) 515 516 if !tc.wantWriteAndUpload { 517 if _, err := os.Stat(filepath.Join(out, "ubuntu-report")); err == nil || (err != nil && !os.IsNotExist(err)) { 518 t.Fatal("we didn't want to get a report but we got one") 519 } 520 return 521 } 522 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 523 data, err := ioutil.ReadFile(p) 524 if err != nil { 525 t.Fatalf("couldn't open report file %s", out) 526 } 527 d := string(data) 528 expected := sysmetrics.ExpectedReportItem 529 if tc.sendOnlyOptOutData { 530 expected = sysmetrics.OptOutJSON 531 } 532 if !strings.Contains(d, expected) { 533 t.Errorf("we expected to find %s in report file, got: %s", expected, d) 534 } 535 }) 536 } 537 } 538 539 func TestCollectAndSendOnUpgrade(t *testing.T) { 540 // we change current path and env variable: not parallelizable tests 541 helper.SkipIfShort(t) 542 543 testCases := []struct { 544 name string 545 previousReportP string 546 547 shouldHitServer bool 548 wantOptOut bool 549 wantErr bool 550 }{ 551 {"with previous report, previous release opt in", 552 "testdata/previous_reports/previous_release_optin", 553 true, false, false}, 554 {"with previous report, previous release opt out", 555 "testdata/previous_reports/previous_release_optout", 556 true, true, false}, 557 } 558 for _, tc := range testCases { 559 tc := tc // capture range variable for parallel execution 560 t.Run(tc.name, func(t *testing.T) { 561 a := helper.Asserter{T: t} 562 563 out, tearDown := helper.TempDir(t) 564 defer tearDown() 565 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 566 out = filepath.Join(out, "ubuntu-report") 567 // we don't really care where we hit for this API integration test, internal ones test it 568 // and we don't really control /etc/os-release version and id. 569 // Same for report file 570 serverHit := false 571 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 572 serverHit = true 573 })) 574 defer ts.Close() 575 576 if tc.previousReportP != "" { 577 if err := os.MkdirAll(out, 0700); err != nil { 578 t.Fatalf("couldn't create report directory: %v", err) 579 } 580 files, err := ioutil.ReadDir(tc.previousReportP) 581 if err != nil { 582 t.Fatalf("couldn't list files under %s: %v", tc.previousReportP, err) 583 } 584 for _, file := range files { 585 data, err := ioutil.ReadFile(filepath.Join(tc.previousReportP, file.Name())) 586 if err != nil { 587 t.Fatalf("couldn't read report file: %v", err) 588 } 589 if err = ioutil.WriteFile(filepath.Join(out, file.Name()), data, 0644); err != nil { 590 t.Fatalf("couldn't write to destination report file in setup: %v", err) 591 } 592 } 593 } 594 595 err := sysmetrics.CollectAndSendOnUpgrade(false, ts.URL) 596 597 if err != nil { 598 t.Fatal("we didn't expect getting an error, got:", err) 599 } 600 601 a.Equal(serverHit, tc.shouldHitServer) 602 603 // get highest report path 604 reportP := "" 605 files, err := ioutil.ReadDir(out) 606 if err != nil { 607 t.Fatalf("couldn't scan %s: %v", out, err) 608 } 609 for _, f := range files { 610 if f.Name() > reportP { 611 reportP = f.Name() 612 } 613 } 614 615 gotF, err := os.Open(filepath.Join(out, reportP)) 616 if err != nil { 617 t.Fatal("didn't generate a report file on disk", err) 618 } 619 got, err := ioutil.ReadAll(gotF) 620 if err != nil { 621 t.Fatal("couldn't read generated report file", err) 622 } 623 isOptOut := strings.Contains(string(got), sysmetrics.OptOutJSON) 624 625 if tc.wantOptOut && !isOptOut { 626 t.Errorf("we wanted an opt out as we opted out in previous release but got some data in: %s", got) 627 } else if !tc.wantOptOut && isOptOut { 628 t.Errorf("we wanted some data which are not opt out information, but got opt out content instead") 629 } 630 }) 631 } 632 } 633 634 func TestSendPendingReport(t *testing.T) { 635 // we change current path and env variable: not parallelizable tests 636 helper.SkipIfShort(t) 637 638 testCases := []struct { 639 name string 640 641 shouldHitServer bool 642 wantErr bool 643 }{ 644 {"regular send", true, false}, 645 } 646 for _, tc := range testCases { 647 tc := tc // capture range variable for parallel execution 648 t.Run(tc.name, func(t *testing.T) { 649 a := helper.Asserter{T: t} 650 651 out, tearDown := helper.TempDir(t) 652 defer tearDown() 653 defer helper.ChangeEnv("XDG_CACHE_HOME", out)() 654 out = filepath.Join(out, "ubuntu-report") 655 656 pendingReportData, err := ioutil.ReadFile(filepath.Join("testdata", "good", "ubuntu-report", "pending")) 657 if err != nil { 658 t.Fatalf("couldn't open pending report file: %v", err) 659 } 660 pendingReportPath := filepath.Join(out, "pending") 661 if err := os.MkdirAll(out, 0700); err != nil { 662 t.Fatal("couldn't create parent directory of pending report", err) 663 } 664 if err := ioutil.WriteFile(pendingReportPath, pendingReportData, 0644); err != nil { 665 t.Fatalf("couldn't copy pending report file to cache directory: %v", err) 666 } 667 668 // we don't really care where we hit for this API integration test, internal ones test it 669 // and we don't really control /etc/os-release version and id. 670 // Same for report file 671 serverHit := false 672 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 673 serverHit = true 674 })) 675 defer ts.Close() 676 677 err = sysmetrics.SendPendingReport(ts.URL) 678 679 a.CheckWantedErr(err, tc.wantErr) 680 a.Equal(serverHit, tc.shouldHitServer) 681 682 if _, pendingReportErr := os.Stat(pendingReportPath); os.IsExist(pendingReportErr) { 683 t.Errorf("we expected the pending report to be removed and it wasn't") 684 } 685 686 p := filepath.Join(out, helper.FindInDirectory(t, "", out)) 687 got, err := ioutil.ReadFile(p) 688 if err != nil { 689 t.Fatalf("couldn't open report file %s", out) 690 } 691 a.Equal(got, pendingReportData) 692 }) 693 } 694 }