Don't NPE if user isn't in tenant (#2678)

Was causing panics when trying to access kopia stats. Panic was recovered from, but reading the error was difficult.

Add some CLI tests to hopefully stop future regressions for this specific case

---

#### Does this PR need a docs update or release note?

- [x]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [ ]  No

#### Type of change

- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

* closes #2668

#### Test Plan

- [x] 💪 Manual
- [ ]  Unit test
- [x] 💚 E2E
This commit is contained in:
ashmrtn 2023-02-28 12:13:34 -08:00 committed by GitHub
parent a595dd1b9b
commit 04516692f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 0 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Corso-generated .meta files and permissions no longer appear in the backup details.
- Panic and recovery if a user didn't exist in the tenant.
### Known Issues
- Folders and Calendars containing zero items or subfolders are not included in the backup.

View File

@ -203,6 +203,47 @@ func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd() {
}
}
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_UserNotInTenant() {
recorder := strings.Builder{}
for _, set := range backupDataSets {
recorder.Reset()
suite.Run(set.String(), func() {
t := suite.T()
ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr)
defer flush()
cmd := tester.StubRootCmd(
"backup", "create", "exchange",
"--config-file", suite.cfgFP,
"--"+utils.UserFN, "foo@nothere.com",
"--"+utils.DataFN, set.String())
cli.BuildCommandTree(cmd)
cmd.SetOut(&recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.Error(t, err)
assert.Contains(
t,
err.Error(),
"not found within tenant", "error missing user not found")
assert.NotContains(t, err.Error(), "runtime error", "panic happened")
t.Logf("backup error message: %s", err.Error())
result := recorder.String()
t.Log("backup results", result)
})
}
}
// ---------------------------------------------------------------------------
// tests prepared with a previous backup
// ---------------------------------------------------------------------------

View File

@ -113,6 +113,41 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupListCmd_empty() {
assert.Equal(t, "No backups available\n", result)
}
func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() {
recorder := strings.Builder{}
t := suite.T()
ctx, flush := tester.NewContext()
defer flush()
ctx = config.SetViper(ctx, suite.vpr)
cmd := tester.StubRootCmd(
"backup", "create", "onedrive",
"--config-file", suite.cfgFP,
"--"+utils.UserFN, "foo@nothere.com")
cli.BuildCommandTree(cmd)
cmd.SetOut(&recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.Error(t, err)
assert.Contains(
t,
err.Error(),
"not found within tenant", "error missing user not found")
assert.NotContains(t, err.Error(), "runtime error", "panic happened")
t.Logf("backup error message: %s", err.Error())
result := recorder.String()
t.Log("backup results", result)
}
// ---------------------------------------------------------------------------
// tests for deleting backups
// ---------------------------------------------------------------------------

View File

@ -627,6 +627,11 @@ func (op *BackupOperation) persistResults(
op.Status = Failed
}
if opStats.k == nil {
op.Status = Failed
return errors.New("backup persistence never completed")
}
op.Results.BytesRead = opStats.k.TotalHashedBytes
op.Results.BytesUploaded = opStats.k.TotalUploadedBytes
op.Results.ItemsWritten = opStats.k.TotalFileCount