derive test userID from test config (#465)

In order to both maintain control of test env data, as
well as ensure open-source users are able to run the
integration tests on personal account data, the test
user must be derived from the test configuration, rather
than hardcoded within the tests.
This commit is contained in:
Keepers 2022-08-02 13:13:23 -06:00 committed by GitHub
parent a785cb5eb4
commit 640dfcf967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 74 additions and 16 deletions

View File

@ -61,8 +61,10 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_setTenantUsers()
}
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataCollection() {
userID, err := tester.M365UserID()
require.NoError(suite.T(), err)
sel := selectors.NewExchangeBackup()
sel.Include(sel.Users([]string{"lidiah@8qzvrj.onmicrosoft.com"}))
sel.Include(sel.Users([]string{userID}))
collectionList, err := suite.connector.ExchangeDataCollection(context.Background(), sel.Selector)
assert.NotNil(suite.T(), collectionList, "collection list")
assert.Nil(suite.T(), err)
@ -102,13 +104,14 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_restoreMessages(
// TestGraphConnector_CreateAndDeleteFolder ensures msgraph application has the ability
// to create and remove folders within the tenant
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_CreateAndDeleteFolder() {
user := "lidiah@8qzvrj.onmicrosoft.com"
userID, err := tester.M365UserID()
require.NoError(suite.T(), err)
now := time.Now()
folderName := "TestFolder: " + common.FormatSimpleDateTime(now)
aFolder, err := exchange.CreateMailFolder(&suite.connector.graphService, user, folderName)
aFolder, err := exchange.CreateMailFolder(&suite.connector.graphService, userID, folderName)
assert.NoError(suite.T(), err, support.ConnectorStackErrorTrace(err))
if aFolder != nil {
err = exchange.DeleteMailFolder(&suite.connector.graphService, user, *aFolder.GetId())
err = exchange.DeleteMailFolder(&suite.connector.graphService, userID, *aFolder.GetId())
assert.NoError(suite.T(), err)
}
}
@ -116,9 +119,10 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_CreateAndDeleteF
// TestGraphConnector_GetMailFolderID verifies the ability to retrieve folder ID of folders
// at the top level of the file tree
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_GetMailFolderID() {
user := "lidiah@8qzvrj.onmicrosoft.com"
userID, err := tester.M365UserID()
require.NoError(suite.T(), err)
folderName := "Inbox"
folderID, err := exchange.GetMailFolderID(&suite.connector.graphService, folderName, user)
folderID, err := exchange.GetMailFolderID(&suite.connector.graphService, folderName, userID)
assert.NoError(suite.T(), err)
assert.NotNil(suite.T(), folderID)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/alcionai/corso/internal/common"
"github.com/alcionai/corso/internal/data"
"github.com/alcionai/corso/internal/tester"
"github.com/alcionai/corso/pkg/backup/details"
)
@ -88,8 +89,13 @@ func (med *MockExchangeData) Info() details.ItemInfo {
// Contents verified as working with sample data from kiota-serialization-json-go v0.5.5
func getMockMessageBytes(subject string) []byte {
userID, err := tester.M365UserID()
if err != nil {
userID = "lidiah@8qzvrj.onmicrosoft.com"
}
message := "{\n \"@odata.etag\": \"W/\\\"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\\\"\",\n \"id\": \"AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8_7BwB8wYc0thTTTYl3RpEYIUq_AAAAAAEMAAB8wYc0thTTTYl3RpEYIUq_AAAZ3wG3AAA=\",\n \"createdDateTime\": \"2022-04-08T18:08:02Z\",\n \"lastModifiedDateTime\": \"2022-05-17T13:46:55Z\",\n \"changeKey\": \"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\",\n \"categories\": [],\n \"receivedDateTime\": \"2022-04-08T18:08:02Z\",\n \"sentDateTime\": \"2022-04-08T18:07:53Z\",\n \"hasAttachments\": false,\n \"internetMessageId\": \"<MWHPR1401MB1952C46D4A46B6398F562B0FA6E99@MWHPR1401MB1952.namprd14.prod.outlook.com>\",\n \"subject\": \"" +
subject + " " + common.FormatSimpleDateTime(time.Now()) + " Different\",\n \"bodyPreview\": \"Who is coming to next week's party? I cannot imagine it is July soon\",\n \"importance\": \"normal\",\n \"parentFolderId\": \"AQMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4ADVkZWQwNmNlMTgALgAAAw_9XBStqZdPuOVIalVTz7sBAHzBhzS2FNNNiXdGkRghSr4AAAIBDAAAAA==\",\n \"conversationId\": \"AAQkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOAAQAI7SSzmEPaRJsY-TWIALn1g=\",\n \"conversationIndex\": \"AQHYS3N3jtJLOYQ9pEmxj9NYgAufWA==\",\n \"isDeliveryReceiptRequested\": null,\n \"isReadReceiptRequested\": false,\n \"isRead\": true,\n \"isDraft\": false,\n \"webLink\": \"https://outlook.office365.com/owa/?ItemID=AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8%2B7BwB8wYc0thTTTYl3RpEYIUq%2BAAAAAAEMAAB8wYc0thTTTYl3RpEYIUq%2BAAAZ3wG3AAA%3D&exvsurl=1&viewmodel=ReadMessageItem\",\n \"inferenceClassification\": \"focused\",\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"<html><head><meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\"><meta name=\\\"Generator\\\" content=\\\"Microsoft Word 15 (filtered medium)\\\"><style><!--@font-face{font-family:\\\"Cambria Math\\\"}@font-face{font-family:Calibri}p.MsoNormal, li.MsoNormal, div.MsoNormal{margin:0in;font-size:11.0pt;font-family:\\\"Calibri\\\",sans-serif}span.EmailStyle17{font-family:\\\"Calibri\\\",sans-serif;color:windowtext}.MsoChpDefault{font-family:\\\"Calibri\\\",sans-serif}@page WordSection1{margin:1.0in 1.0in 1.0in 1.0in}div.WordSection1{}--></style></head><body lang=\\\"EN-US\\\" link=\\\"#0563C1\\\" vlink=\\\"#954F72\\\" style=\\\"word-wrap:break-word\\\"><div class=\\\"WordSection1\\\"><p class=\\\"MsoNormal\\\">I've been going through with the changing of messages. It shouldn't have the same calls, right? Call Me? </p><p class=\\\"MsoNormal\\\">&nbsp;</p><p class=\\\"MsoNormal\\\">We want to be able to send multiple messages and we want to be able to respond and do other things that make sense for our users. In this case. Lets consider a Mailbox</p></div></body></html>\"\n },\n \"sender\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"from\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"name\": \"Dustin Abbot\",\n \"address\": \"dustina@8qzvrj.onmicrosoft.com\"\n }\n }\n ],\n \"ccRecipients\": [],\n \"bccRecipients\": [],\n \"replyTo\": [],\n \"flag\": {\n \"flagStatus\": \"notFlagged\"\n }\n}\n"
subject + " " + common.FormatSimpleDateTime(time.Now()) + " Different\",\n \"bodyPreview\": \"Who is coming to next week's party? I cannot imagine it is July soon\",\n \"importance\": \"normal\",\n \"parentFolderId\": \"AQMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4ADVkZWQwNmNlMTgALgAAAw_9XBStqZdPuOVIalVTz7sBAHzBhzS2FNNNiXdGkRghSr4AAAIBDAAAAA==\",\n \"conversationId\": \"AAQkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOAAQAI7SSzmEPaRJsY-TWIALn1g=\",\n \"conversationIndex\": \"AQHYS3N3jtJLOYQ9pEmxj9NYgAufWA==\",\n \"isDeliveryReceiptRequested\": null,\n \"isReadReceiptRequested\": false,\n \"isRead\": true,\n \"isDraft\": false,\n \"webLink\": \"https://outlook.office365.com/owa/?ItemID=AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8%2B7BwB8wYc0thTTTYl3RpEYIUq%2BAAAAAAEMAAB8wYc0thTTTYl3RpEYIUq%2BAAAZ3wG3AAA%3D&exvsurl=1&viewmodel=ReadMessageItem\",\n \"inferenceClassification\": \"focused\",\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"<html><head><meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\"><meta name=\\\"Generator\\\" content=\\\"Microsoft Word 15 (filtered medium)\\\"><style><!--@font-face{font-family:\\\"Cambria Math\\\"}@font-face{font-family:Calibri}p.MsoNormal, li.MsoNormal, div.MsoNormal{margin:0in;font-size:11.0pt;font-family:\\\"Calibri\\\",sans-serif}span.EmailStyle17{font-family:\\\"Calibri\\\",sans-serif;color:windowtext}.MsoChpDefault{font-family:\\\"Calibri\\\",sans-serif}@page WordSection1{margin:1.0in 1.0in 1.0in 1.0in}div.WordSection1{}--></style></head><body lang=\\\"EN-US\\\" link=\\\"#0563C1\\\" vlink=\\\"#954F72\\\" style=\\\"word-wrap:break-word\\\"><div class=\\\"WordSection1\\\"><p class=\\\"MsoNormal\\\">I've been going through with the changing of messages. It shouldn't have the same calls, right? Call Me? </p><p class=\\\"MsoNormal\\\">&nbsp;</p><p class=\\\"MsoNormal\\\">We want to be able to send multiple messages and we want to be able to respond and do other things that make sense for our users. In this case. Lets consider a Mailbox</p></div></body></html>\"\n },\n \"sender\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"" + userID + "\"\n }\n },\n \"from\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"name\": \"Dustin Abbot\",\n \"address\": \"dustina@8qzvrj.onmicrosoft.com\"\n }\n }\n ],\n \"ccRecipients\": [],\n \"bccRecipients\": [],\n \"replyTo\": [],\n \"flag\": {\n \"flagStatus\": \"notFlagged\"\n }\n}\n"
return []byte(message)
}

View File

@ -131,7 +131,8 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run() {
t := suite.T()
ctx := context.Background()
m365User := "lidiah@8qzvrj.onmicrosoft.com"
m365UserID, err := tester.M365UserID()
require.NoError(suite.T(), err)
acct, err := tester.NewM365Account()
require.NoError(t, err)
@ -157,7 +158,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run() {
sw := store.NewKopiaStore(ms)
sel := selectors.NewExchangeBackup()
sel.Include(sel.Users([]string{m365User}))
sel.Include(sel.Users([]string{m365UserID}))
bo, err := NewBackupOperation(
ctx,

View File

@ -129,7 +129,8 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
t := suite.T()
ctx := context.Background()
m365User := "lidiah@8qzvrj.onmicrosoft.com"
m365UserID, err := tester.M365UserID()
require.NoError(suite.T(), err)
acct, err := tester.NewM365Account()
require.NoError(t, err)
@ -152,7 +153,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
sw := store.NewKopiaStore(ms)
bsel := selectors.NewExchangeBackup()
bsel.Include(bsel.Users([]string{m365User}))
bsel.Include(bsel.Users([]string{m365UserID}))
bo, err := NewBackupOperation(
ctx,
@ -166,7 +167,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
require.NotEmpty(t, bo.Results.BackupID)
rsel := selectors.NewExchangeRestore()
rsel.Include(rsel.Users([]string{m365User}))
rsel.Include(rsel.Users([]string{m365UserID}))
ro, err := NewRestoreOperation(
ctx,
@ -192,7 +193,8 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() {
t := suite.T()
ctx := context.Background()
m365User := "lidiah@8qzvrj.onmicrosoft.com"
m365UserID, err := tester.M365UserID()
require.NoError(suite.T(), err)
acct, err := tester.NewM365Account()
require.NoError(t, err)
@ -215,7 +217,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() {
sw := store.NewKopiaStore(ms)
bsel := selectors.NewExchangeBackup()
bsel.Include(bsel.Users([]string{m365User}))
bsel.Include(bsel.Users([]string{m365UserID}))
bo, err := NewBackupOperation(
ctx,

View File

@ -16,7 +16,7 @@ var M365AcctCredEnvs = []string{
func NewM365Account() (account.Account, error) {
cfg, err := readTestConfig()
if err != nil {
return account.Account{}, errors.Wrap(err, "configuring m365 account from test file")
return account.Account{}, errors.Wrap(err, "configuring m365 account from test configuration")
}
return account.NewAccount(

View File

@ -18,8 +18,29 @@ const (
// M365 config
testCfgTenantID = "tenantid"
testCfgUserID = "m365userid"
)
// test specific env vars
const (
EnvCorsoM365TestUserID = "CORSO_M356_TEST_USER_ID"
)
// global to hold the test config results.
var testConfig map[string]string
// call this instead of returning testConfig directly.
func cloneTestConfig() map[string]string {
if testConfig == nil {
return map[string]string{}
}
clone := map[string]string{}
for k, v := range testConfig {
clone[k] = v
}
return clone
}
func newTestViper() (*viper.Viper, error) {
vpr := viper.New()
@ -48,6 +69,10 @@ func newTestViper() (*viper.Viper, error) {
// local integration test controls. Populates values with
// defaults where standard.
func readTestConfig() (map[string]string, error) {
if testConfig != nil {
return cloneTestConfig(), nil
}
vpr, err := newTestViper()
if err != nil {
return nil, err
@ -66,8 +91,10 @@ func readTestConfig() (map[string]string, error) {
fallbackTo(testEnv, testCfgEndpoint, vpr.GetString(testCfgEndpoint), "s3.amazonaws.com")
fallbackTo(testEnv, testCfgPrefix, vpr.GetString(testCfgPrefix))
fallbackTo(testEnv, testCfgTenantID, os.Getenv(account.TenantID), vpr.GetString(testCfgTenantID))
fallbackTo(testEnv, testCfgUserID, os.Getenv(EnvCorsoM365TestUserID), vpr.GetString(testCfgTenantID), "lidiah@8qzvrj.onmicrosoft.com")
return testEnv, nil
testConfig = testEnv
return cloneTestConfig(), nil
}
// writes the first non-zero valued string to the map at the key.

View File

@ -0,0 +1,18 @@
package tester
import (
"github.com/pkg/errors"
)
// M365UserID returns an userID string representing the m365UserID described
// by either the env var CORSO_M356_TEST_USER_ID, the corso_test.toml config
// file or the default value (in that order of priority). The default is a
// last-attempt fallback that will only work on alcion's testing org.
func M365UserID() (string, error) {
cfg, err := readTestConfig()
if err != nil {
return "", errors.Wrap(err, "retrieving m365 user id from test configuration")
}
return cfg[testCfgUserID], nil
}