corso/src/cmd/sanity_test/sanity_tests.go
neha_gupta 11677fdefb
Release Sanity test (#2622)
## Description

Github workflow - Release sanity test which can run pre and post
release.
Testing- 
- version command
- repo init and connect
- backup and restore of exchange and onedrive
-  verify correct no. of emails restored
- verify file sizes restored and roles on folder are correct.
- incremental backup and verification of the same

**Further enhancement-**
- check actual email data instead of just no. of emails
- verify contacts and calendar
- permission in onedrive
- slack notification on failure 
- if we recieve an email in between a backup and restore, we will fail
the test as the counts won't match

**issues for handling enhancement-** 
https://github.com/alcionai/corso/issues/2743
https://github.com/alcionai/corso/issues/2742

## Does this PR need a docs update or release note?
- [ ]  No 

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🤖 Test

## Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic
words" - "closes, fixes" to auto-close the Github issue. -->
* https://github.com/alcionai/corso/pull/2622/

## Test Plan
- [ ] 💪 Manual
2023-03-10 17:46:40 +05:30

232 lines
5.9 KiB
Go

package main
import (
"context"
"fmt"
"os"
"reflect"
"strings"
"time"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/microsoftgraph/msgraph-sdk-go/users"
)
func main() {
adapter, err := graph.CreateAdapter(
os.Getenv("AZURE_TENANT_ID"),
os.Getenv("AZURE_CLIENT_ID"),
os.Getenv("AZURE_CLIENT_SECRET"),
)
if err != nil {
fmt.Println("error while creating adapter: ", err)
os.Exit(1)
return
}
testUser := os.Getenv("CORSO_M365_TEST_USER_ID")
folder := strings.TrimSpace(os.Getenv("RESTORE_FOLDER"))
restoreStartTime := strings.SplitAfter(folder, "Corso_Restore_")[1]
startTime, _ := time.Parse(time.RFC822, restoreStartTime)
fmt.Println("Restore folder: ", folder)
client := msgraphsdk.NewGraphServiceClient(adapter)
switch service := os.Getenv("RESTORE_SERVICE"); service {
case "exchange":
checkEmailRestoration(client, testUser, folder, startTime)
default:
checkOnedriveRestoration(client, testUser, folder, startTime)
}
}
func checkEmailRestoration(client *msgraphsdk.GraphServiceClient, testUser, folderName string, startTime time.Time) {
var (
messageCount = make(map[string]int32)
restoreFolder models.MailFolderable
)
builder := client.UsersById(testUser).MailFolders()
for {
result, err := builder.Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting the drive: %v\n", err)
os.Exit(1)
}
res := result.GetValue()
for _, r := range res {
name := *r.GetDisplayName()
var rStartTime time.Time
restoreStartTime := strings.SplitAfter(name, "Corso_Restore_")
if len(restoreStartTime) > 1 {
rStartTime, _ = time.Parse(time.RFC822, restoreStartTime[1])
if startTime.Before(rStartTime) {
fmt.Printf("The restore folder %s was created after %s. Will skip check.", name, folderName)
continue
}
}
if name == folderName {
restoreFolder = r
continue
}
messageCount[*r.GetDisplayName()] = *r.GetTotalItemCount()
}
link, ok := ptr.ValOK(result.GetOdataNextLink())
if !ok {
break
}
builder = users.NewItemMailFoldersRequestBuilder(link, client.GetAdapter())
}
user := client.UsersById(testUser)
folder := user.MailFoldersById(*restoreFolder.GetId())
childFolder, err := folder.ChildFolders().Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting the drive: %v\n", err)
os.Exit(1)
}
for _, restore := range childFolder.GetValue() {
if messageCount[*restore.GetDisplayName()] != *restore.GetTotalItemCount() {
fmt.Println("Restore was not succesfull for: ",
*restore.GetDisplayName(),
"Folder count: ",
messageCount[*restore.GetDisplayName()],
"Restore count: ",
*restore.GetTotalItemCount())
os.Exit(1)
}
}
}
func checkOnedriveRestoration(client *msgraphsdk.GraphServiceClient, testUser, folderName string, startTime time.Time) {
file := make(map[string]int64)
folderPermission := make(map[string][]string)
restoreFolderID := ""
drive, err := client.UsersById(testUser).Drive().Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting the drive: %v\n", err)
os.Exit(1)
}
response, err := client.DrivesById(*drive.GetId()).Root().Children().Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting drive by id: %v\n", err)
os.Exit(1)
}
for _, driveItem := range response.GetValue() {
if *driveItem.GetName() == folderName {
restoreFolderID = *driveItem.GetId()
continue
}
var rStartTime time.Time
restoreStartTime := strings.SplitAfter(*driveItem.GetName(), "Corso_Restore_")
if len(restoreStartTime) > 1 {
rStartTime, _ = time.Parse(time.RFC822, restoreStartTime[1])
if startTime.Before(rStartTime) {
fmt.Printf("The restore folder %s was created after %s. Will skip check.", *driveItem.GetName(), folderName)
continue
}
}
// if it's a file check the size
if driveItem.GetFile() != nil {
file[*driveItem.GetName()] = *driveItem.GetSize()
}
if driveItem.GetFolder() != nil {
permission, err := client.
DrivesById(*drive.GetId()).
ItemsById(*driveItem.GetId()).
Permissions().
Get(context.TODO(), nil)
if err != nil {
fmt.Printf("Error getting item by id: %v\n", err)
os.Exit(1)
}
// check if permission are correct on folder
for _, permission := range permission.GetValue() {
folderPermission[*driveItem.GetName()] = permission.GetRoles()
}
continue
}
}
checkFileData(client, *drive.GetId(), restoreFolderID, file, folderPermission)
fmt.Println("Success")
}
func checkFileData(
client *msgraphsdk.GraphServiceClient,
driveID,
restoreFolderID string,
file map[string]int64,
folderPermission map[string][]string,
) {
itemBuilder := client.DrivesById(driveID).ItemsById(restoreFolderID)
restoreResponses, err := itemBuilder.Children().Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting child folder: %v\n", err)
os.Exit(1)
}
for _, restoreData := range restoreResponses.GetValue() {
restoreName := *restoreData.GetName()
if restoreData.GetFile() != nil {
if *restoreData.GetSize() != file[restoreName] {
fmt.Printf("Size of file %s is different in drive %d and restored file: %d ",
restoreName,
file[restoreName],
*restoreData.GetSize())
os.Exit(1)
}
continue
}
itemBuilder := client.DrivesById(driveID).ItemsById(*restoreData.GetId())
permissionColl, err := itemBuilder.Permissions().Get(context.TODO(), nil)
if err != nil {
fmt.Printf("Error getting permission: %v\n", err)
os.Exit(1)
}
userPermission := []string{}
for _, perm := range permissionColl.GetValue() {
userPermission = perm.GetRoles()
}
if !reflect.DeepEqual(folderPermission[restoreName], userPermission) {
fmt.Printf("Permission mismatch for %s.", restoreName)
os.Exit(1)
}
}
}