add a QoL path.Build func (#2763)

Adds a path.Build() func that can arbitrarily build a path according to expected standards without first initializing a path.Builder{}.
---

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

- [x]  No

#### Type of change

- [x] 🧹 Tech Debt/Cleanup

#### Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-03-13 10:56:31 -06:00 committed by GitHub
parent c0fc821976
commit dc21f4ce07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 189 additions and 228 deletions

View File

@ -173,14 +173,13 @@ func buildCollections(
collections := make([]data.RestoreCollection, 0, len(colls))
for _, c := range colls {
pth, err := toDataLayerPath(
service,
pth, err := path.Build(
tenant,
user,
service,
c.category,
c.pathElements,
false,
)
c.pathElements...)
if err != nil {
return nil, err
}
@ -197,22 +196,3 @@ func buildCollections(
return collections, nil
}
func toDataLayerPath(
service path.ServiceType,
tenant, user string,
category path.CategoryType,
elements []string,
isItem bool,
) (path.Path, error) {
pb := path.Builder{}.Append(elements...)
switch service {
case path.ExchangeService:
return pb.ToDataLayerExchangePathForCategory(tenant, user, category, isItem)
case path.OneDriveService:
return pb.ToDataLayerOneDrivePath(tenant, user, isItem)
}
return nil, errors.Errorf("unknown service %s", service.String())
}

View File

@ -570,27 +570,25 @@ func (suite *FolderCacheIntegrationSuite) TestCreateContainerDestination() {
name: "Mail Cache Test",
category: path.EmailCategory,
pathFunc1: func(t *testing.T) path.Path {
pth, err := path.Builder{}.
Append("Griffindor").
Append("Croix").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.EmailCategory,
false)
false,
"Griffindor", "Croix")
require.NoError(t, err)
return pth
},
pathFunc2: func(t *testing.T) path.Path {
pth, err := path.Builder{}.
Append("Griffindor").
Append("Felicius").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.EmailCategory,
false)
false,
"Griffindor", "Felicius")
require.NoError(t, err)
return pth
@ -600,28 +598,28 @@ func (suite *FolderCacheIntegrationSuite) TestCreateContainerDestination() {
name: "Contact Cache Test",
category: path.ContactsCategory,
pathFunc1: func(t *testing.T) path.Path {
aPath, err := path.Builder{}.
Append("HufflePuff").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.ContactsCategory,
false)
false,
"HufflePuff")
require.NoError(t, err)
return aPath
return pth
},
pathFunc2: func(t *testing.T) path.Path {
aPath, err := path.Builder{}.
Append("Ravenclaw").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.ContactsCategory,
false)
false,
"Ravenclaw")
require.NoError(t, err)
return aPath
return pth
},
},
{
@ -629,28 +627,28 @@ func (suite *FolderCacheIntegrationSuite) TestCreateContainerDestination() {
category: path.EventsCategory,
useIDForPath: true,
pathFunc1: func(t *testing.T) path.Path {
aPath, err := path.Builder{}.
Append("Durmstrang").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.EventsCategory,
false)
false,
"Durmstrang")
require.NoError(t, err)
return aPath
return pth
},
pathFunc2: func(t *testing.T) path.Path {
aPath, err := path.Builder{}.
Append("Beauxbatons").
ToDataLayerExchangePathForCategory(
pth, err := path.Build(
suite.credentials.AzureTenantID,
user,
path.ExchangeService,
path.EventsCategory,
false)
false,
"Beauxbatons")
require.NoError(t, err)
return aPath
return pth
},
},
}

View File

@ -86,12 +86,13 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeData_FullPath() {
user := "a-user"
folder := "a-folder"
fullPath, err := path.Builder{}.Append(folder).ToDataLayerExchangePathForCategory(
fullPath, err := path.Build(
tenant,
user,
path.ExchangeService,
path.EmailCategory,
false,
)
folder)
require.NoError(t, err)
edc := Collection{
@ -104,18 +105,18 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeData_FullPath() {
func (suite *ExchangeDataCollectionSuite) TestExchangeDataCollection_NewExchangeDataCollection() {
t := suite.T()
tenant := "a-tenant"
user := "a-user"
folder := "a-folder"
name := "User"
fullPath, err := path.Builder{}.Append(folder).ToDataLayerExchangePathForCategory(
fullPath, err := path.Build(
tenant,
user,
path.ExchangeService,
path.EmailCategory,
false,
)
folder)
require.NoError(t, err)
edc := Collection{
@ -127,17 +128,11 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeDataCollection_NewExchange
}
func (suite *ExchangeDataCollectionSuite) TestNewCollection_state() {
fooP, err := path.Builder{}.
Append("foo").
ToDataLayerExchangePathForCategory("t", "u", path.EmailCategory, false)
fooP, err := path.Build("t", "u", path.ExchangeService, path.EmailCategory, false, "foo")
require.NoError(suite.T(), err)
barP, err := path.Builder{}.
Append("bar").
ToDataLayerExchangePathForCategory("t", "u", path.EmailCategory, false)
barP, err := path.Build("t", "u", path.ExchangeService, path.EmailCategory, false, "bar")
require.NoError(suite.T(), err)
locP, err := path.Builder{}.
Append("human-readable").
ToDataLayerExchangePathForCategory("t", "u", path.EmailCategory, false)
locP, err := path.Build("t", "u", path.ExchangeService, path.EmailCategory, false, "human-readable")
require.NoError(suite.T(), err)
table := []struct {

View File

@ -534,9 +534,7 @@ func (suite *ServiceIteratorsSuite) TestFilterContainersAndFillCollections_incre
)
prevPath := func(t *testing.T, at ...string) path.Path {
p, err := path.Builder{}.
Append(at...).
ToDataLayerExchangePathForCategory(tenantID, userID, cat, false)
p, err := path.Build(tenantID, userID, path.ExchangeService, cat, false, at...)
require.NoError(t, err)
return p

View File

@ -89,15 +89,13 @@ func (suite *MetadataUnitSuite) TestIsMetadataFile_Files_MetaSuffixes() {
suite.Run(fmt.Sprintf("%s %s %s", test.service, test.category, ext), func() {
t := suite.T()
p, err := path.Builder{}.
Append("file"+ext).
ToDataLayerPath(
p, err := path.Build(
tenant,
user,
test.service,
test.category,
true,
)
"file"+ext)
require.NoError(t, err)
test.expected(t, metadata.IsMetadataFile(p), "extension %s", ext)
@ -112,15 +110,13 @@ func (suite *MetadataUnitSuite) TestIsMetadataFile_Files_NotMetaSuffixes() {
suite.Run(fmt.Sprintf("%s %s %s", test.service, test.category, ext), func() {
t := suite.T()
p, err := path.Builder{}.
Append("file"+ext).
ToDataLayerPath(
p, err := path.Build(
tenant,
user,
test.service,
test.category,
true,
)
"file"+ext)
require.NoError(t, err)
assert.Falsef(t, metadata.IsMetadataFile(p), "extension %s", ext)
@ -137,15 +133,13 @@ func (suite *MetadataUnitSuite) TestIsMetadataFile_Directories() {
suite.Run(fmt.Sprintf("%s %s %s", test.service, test.category, ext), func() {
t := suite.T()
p, err := path.Builder{}.
Append("file"+ext).
ToDataLayerPath(
p, err := path.Build(
tenant,
user,
test.service,
test.category,
false,
)
"file"+ext)
require.NoError(t, err)
assert.Falsef(t, metadata.IsMetadataFile(p), "extension %s", ext)

View File

@ -27,14 +27,13 @@ func TestMetadataCollectionUnitSuite(t *testing.T) {
func (suite *MetadataCollectionUnitSuite) TestFullPath() {
t := suite.T()
p, err := path.Builder{}.
Append("foo").
ToDataLayerExchangePathForCategory(
p, err := path.Build(
"a-tenant",
"a-user",
path.ExchangeService,
path.EmailCategory,
false,
)
"foo")
require.NoError(t, err)
c := NewMetadataCollection(p, nil, nil)
@ -70,14 +69,13 @@ func (suite *MetadataCollectionUnitSuite) TestItems() {
items = append(items, NewMetadataItem(itemNames[i], itemData[i]))
}
p, err := path.Builder{}.
Append("foo").
ToDataLayerExchangePathForCategory(
p, err := path.Build(
"a-tenant",
"a-user",
path.ExchangeService,
path.EmailCategory,
false,
)
"foo")
require.NoError(t, err)
c := NewMetadataCollection(

View File

@ -11,7 +11,6 @@ import (
"testing"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
@ -37,27 +36,7 @@ func mustToDataLayerPath(
elements []string,
isItem bool,
) path.Path {
var (
err error
res path.Path
)
pb := path.Builder{}.Append(elements...)
switch service {
case path.ExchangeService:
res, err = pb.ToDataLayerExchangePathForCategory(tenant, resourceOwner, category, isItem)
case path.OneDriveService:
require.Equal(t, path.FilesCategory, category)
res, err = pb.ToDataLayerOneDrivePath(tenant, resourceOwner, isItem)
case path.SharePointService:
res, err = pb.ToDataLayerSharePointPath(tenant, resourceOwner, category, isItem)
default:
err = errors.Errorf("bad service type %s", service.String())
}
res, err := path.Build(tenant, resourceOwner, service, category, isItem, elements...)
require.NoError(t, err)
return res

View File

@ -83,12 +83,13 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
itemName: "MockListing",
category: List,
getDir: func(t *testing.T) path.Path {
dir, err := path.Builder{}.Append(dirRoot).
ToDataLayerSharePointPath(
dir, err := path.Build(
tenant,
user,
path.SharePointService,
path.ListsCategory,
false)
false,
dirRoot)
require.NoError(t, err)
return dir
@ -118,12 +119,13 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
itemName: "MockPages",
category: Pages,
getDir: func(t *testing.T) path.Path {
dir, err := path.Builder{}.Append(dirRoot).
ToDataLayerSharePointPath(
dir, err := path.Build(
tenant,
user,
path.SharePointService,
path.PagesCategory,
false)
false,
dirRoot)
require.NoError(t, err)
return dir

View File

@ -141,12 +141,13 @@ func collectLists(
break
}
dir, err := path.Builder{}.Append(tuple.name).
ToDataLayerSharePointPath(
dir, err := path.Build(
tenantID,
siteID,
path.SharePointService,
path.ListsCategory,
false)
false,
tuple.name)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "creating list collection path").WithClues(ctx))
}
@ -234,12 +235,13 @@ func collectPages(
break
}
dir, err := path.Builder{}.Append(tuple.Name).
ToDataLayerSharePointPath(
dir, err := path.Build(
creds.AzureTenantID,
siteID,
path.SharePointService,
path.PagesCategory,
false)
false,
tuple.Name)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "creating page collection path").WithClues(ctx))
}

View File

@ -20,13 +20,9 @@ func TestDataCollectionSuite(t *testing.T) {
}
func (suite *DataCollectionSuite) TestStateOf() {
fooP, err := path.Builder{}.
Append("foo").
ToDataLayerExchangePathForCategory("t", "u", path.EmailCategory, false)
fooP, err := path.Build("t", "u", path.ExchangeService, path.EmailCategory, false, "foo")
require.NoError(suite.T(), err)
barP, err := path.Builder{}.
Append("bar").
ToDataLayerExchangePathForCategory("t", "u", path.EmailCategory, false)
barP, err := path.Build("t", "u", path.ExchangeService, path.EmailCategory, false, "bar")
require.NoError(suite.T(), err)
table := []struct {

View File

@ -34,13 +34,13 @@ func TestKopiaDataCollectionUnitSuite(t *testing.T) {
func (suite *KopiaDataCollectionUnitSuite) TestReturnsPath() {
t := suite.T()
b := path.Builder{}.Append("some", "path", "for", "data")
pth, err := b.ToDataLayerExchangePathForCategory(
pth, err := path.Build(
"a-tenant",
"a-user",
path.ExchangeService,
path.EmailCategory,
false,
)
"some", "path", "for", "data")
require.NoError(t, err)
c := kopiaDataCollection{
@ -210,13 +210,13 @@ func (suite *KopiaDataCollectionUnitSuite) TestFetch() {
})
}
b := path.Builder{}.Append(folder1, folder2)
pth, err := b.ToDataLayerExchangePathForCategory(
pth, err := path.Build(
tenant,
user,
path.ExchangeService,
category,
false,
)
folder1, folder2)
require.NoError(suite.T(), err)
table := []struct {

View File

@ -352,15 +352,13 @@ func TestCorsoProgressUnitSuite(t *testing.T) {
}
func (suite *CorsoProgressUnitSuite) SetupSuite() {
p, err := path.Builder{}.Append(
testInboxDir,
"testFile",
).ToDataLayerExchangePathForCategory(
p, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
true,
)
testInboxDir, "testFile")
require.NoError(suite.T(), err)
suite.targetFilePath = p

View File

@ -165,21 +165,25 @@ func TestKopiaIntegrationSuite(t *testing.T) {
}
func (suite *KopiaIntegrationSuite) SetupSuite() {
tmp, err := path.Builder{}.Append(testInboxDir).ToDataLayerExchangePathForCategory(
tmp, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
false)
false,
testInboxDir)
require.NoError(suite.T(), err)
suite.storePath1 = tmp
suite.locPath1 = tmp
tmp, err = path.Builder{}.Append(testArchiveDir).ToDataLayerExchangePathForCategory(
tmp, err = path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
false)
false,
testArchiveDir)
require.NoError(suite.T(), err)
suite.storePath2 = tmp
@ -326,12 +330,13 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
}
func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() {
tmp, err := path.Builder{}.Append(testInboxDir).ToDataLayerPath(
tmp, err := path.Build(
testTenant,
testUser,
path.OneDriveService,
path.FilesCategory,
false)
false,
testInboxDir)
require.NoError(suite.T(), err)
storePath := tmp
@ -741,22 +746,24 @@ func TestKopiaSimpleRepoIntegrationSuite(t *testing.T) {
}
func (suite *KopiaSimpleRepoIntegrationSuite) SetupSuite() {
tmp, err := path.Builder{}.Append(testInboxDir).ToDataLayerExchangePathForCategory(
tmp, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
false,
)
testInboxDir)
require.NoError(suite.T(), err)
suite.testPath1 = tmp
tmp, err = path.Builder{}.Append(testArchiveDir).ToDataLayerExchangePathForCategory(
tmp, err = path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
false,
)
testArchiveDir)
require.NoError(suite.T(), err)
suite.testPath2 = tmp
@ -897,12 +904,13 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
Category: path.EmailCategory,
}
subtreePathTmp, err := path.Builder{}.Append("tmp").ToDataLayerExchangePathForCategory(
subtreePathTmp, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
false,
)
"tmp")
require.NoError(suite.T(), err)
subtreePath := subtreePathTmp.ToBuilder().Dir()
@ -1048,12 +1056,13 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
}
func (suite *KopiaSimpleRepoIntegrationSuite) TestRestoreMultipleItems() {
doesntExist, err := path.Builder{}.Append("subdir", "foo").ToDataLayerExchangePathForCategory(
doesntExist, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
path.EmailCategory,
true,
)
"subdir", "foo")
require.NoError(suite.T(), err)
// Expected items is generated during the test by looking up paths in the

View File

@ -369,13 +369,13 @@ func builderFromReason(ctx context.Context, tenant string, r kopia.Reason) (*pat
// This is hacky, but we want the path package to format the path the right
// way (e.x. proper order for service, category, etc), but we don't care about
// the folders after the prefix.
p, err := path.Builder{}.Append("tmp").ToDataLayerPath(
p, err := path.Build(
tenant,
r.ResourceOwner,
r.Service,
r.Category,
false,
)
"tmp")
if err != nil {
return nil, clues.Wrap(err, "building path").WithClues(ctx)
}

View File

@ -662,14 +662,13 @@ func makeItemPath(
) path.Path {
t.Helper()
p, err := path.Builder{}.Append(elems...).
ToDataLayerPath(
p, err := path.Build(
tenant,
resourceOwner,
service,
category,
true,
)
elems...)
require.NoError(t, err)
return p

View File

@ -48,7 +48,7 @@ func (suite *OneDrivePathSuite) Test_ToOneDrivePath() {
suite.Run(tt.name, func() {
t := suite.T()
p, err := path.Builder{}.Append(tt.pathElements...).ToDataLayerOneDrivePath("tenant", "user", false)
p, err := path.Build("tenant", "user", path.OneDriveService, path.FilesCategory, false, tt.pathElements...)
require.NoError(suite.T(), err)
got, err := path.ToOneDrivePath(p)

View File

@ -376,6 +376,21 @@ func (pb Builder) ToServiceCategoryMetadataPath(
}, nil
}
func Build(
tenant, resourceOwner string,
service ServiceType,
category CategoryType,
hasItem bool,
elements ...string,
) (Path, error) {
b := Builder{}.Append(elements...)
return b.ToDataLayerPath(
tenant, resourceOwner,
service, category,
hasItem)
}
func (pb Builder) ToDataLayerPath(
tenant, user string,
service ServiceType,

View File

@ -184,9 +184,7 @@ func scopeMustHave[T scopeT](t *testing.T, sc T, m map[categorizer]string) {
// stubPath ensures test path production matches that of fullPath design,
// stubbing out static values where necessary.
func stubPath(t *testing.T, user string, s []string, cat path.CategoryType) path.Path {
pth, err := path.Builder{}.
Append(s...).
ToDataLayerExchangePathForCategory("tid", user, cat, true)
pth, err := path.Build("tid", user, path.ExchangeService, cat, true, s...)
require.NoError(t, err)
return pth

View File

@ -257,8 +257,8 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() {
func (suite *OneDriveSelectorSuite) TestOneDriveCategory_PathValues() {
t := suite.T()
pathBuilder := path.Builder{}.Append("drive", "driveID", "root:", "dir1", "dir2", "file")
filePath, err := pathBuilder.ToDataLayerOneDrivePath("tenant", "user", true)
elems := []string{"drive", "driveID", "root:", "dir1", "dir2", "file"}
filePath, err := path.Build("tenant", "user", path.OneDriveService, path.FilesCategory, true, elems...)
require.NoError(t, err)
expected := map[categorizer][]string{

View File

@ -321,8 +321,6 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
}
func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
pathBuilder := path.Builder{}.Append("dir1", "dir2", "item")
table := []struct {
name string
sc sharePointCategory
@ -350,11 +348,13 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
suite.Run(test.name, func() {
t := suite.T()
itemPath, err := pathBuilder.ToDataLayerSharePointPath(
itemPath, err := path.Build(
"tenant",
"site",
path.SharePointService,
test.sc.PathType(),
true)
true,
"dir1", "dir2", "item")
require.NoError(t, err)
ent := details.DetailsEntry{