Skip to content

Commit

Permalink
updated test
Browse files Browse the repository at this point in the history
wonwuakpa-msft committed Jan 16, 2025
1 parent 17921f5 commit 9ef35d5
Showing 10 changed files with 161 additions and 32 deletions.
1 change: 1 addition & 0 deletions common/fe-ste-models.go
Original file line number Diff line number Diff line change
@@ -1119,6 +1119,7 @@ const (
MaxNumberOfBlocksPerBlob = 50000
BlockSizeThreshold = 256 * 1024 * 1024
MinParallelChunkCountThreshold = 4 /* minimum number of chunks in parallel for AzCopy to be performant. */
GigaByte = 1024 * 1024 * 1024
MegaByte = 1024 * 1024
KiloByte = 1024
)
1 change: 1 addition & 0 deletions e2etest/newe2e_assertions.go
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ func (n NoError) MinArgs() int {
func (n NoError) Assert(items ...any) bool {
for _, v := range items {
if v != nil {
fmt.Sprintf("%v in %v is not Nil", v, items)
return false
}
}
3 changes: 3 additions & 0 deletions e2etest/newe2e_resource_manager_mock.go
Original file line number Diff line number Diff line change
@@ -232,6 +232,9 @@ func (m *MockContainerResourceManager) GetProperties(a Asserter) ContainerProper
return ContainerProperties{}
}

func (m *MockContainerResourceManager) SetProperties(a Asserter, properties *ContainerResourceManager) {
}

func (m *MockContainerResourceManager) Delete(a Asserter) {
// No-op it
}
13 changes: 13 additions & 0 deletions e2etest/newe2e_resource_managers_file.go
Original file line number Diff line number Diff line change
@@ -208,6 +208,19 @@ func (s *FileShareResourceManager) GetProperties(a Asserter) ContainerProperties
}
}

// SetProperties Sets the quota of a file share
func (s *FileShareResourceManager) SetProperties(a Asserter, properties *ContainerProperties) {
a.HelperMarker().Helper()
props := DerefOrZero(properties)

_, err := s.internalClient.SetProperties(ctx, &share.SetPropertiesOptions{
Quota: props.FileContainerProperties.Quota})

a.NoError("set share properties", err)

return
}

func (s *FileShareResourceManager) Create(a Asserter, props ContainerProperties) {
a.HelperMarker().Helper()
s.CreateWithOptions(a, &FileShareCreateOptions{
29 changes: 22 additions & 7 deletions e2etest/newe2e_task_runazcopy.go
Original file line number Diff line number Diff line change
@@ -53,13 +53,14 @@ var _ AzCopyStdout = &AzCopyRawStdout{}
type AzCopyVerb string

const ( // initially supporting a limited set of verbs
AzCopyVerbCopy AzCopyVerb = "copy"
AzCopyVerbSync AzCopyVerb = "sync"
AzCopyVerbRemove AzCopyVerb = "remove"
AzCopyVerbList AzCopyVerb = "list"
AzCopyVerbLogin AzCopyVerb = "login"
AzCopyVerbLogout AzCopyVerb = "logout"
AzCopyVerbJobs AzCopyVerb = "jobs"
AzCopyVerbCopy AzCopyVerb = "copy"
AzCopyVerbSync AzCopyVerb = "sync"
AzCopyVerbRemove AzCopyVerb = "remove"
AzCopyVerbList AzCopyVerb = "list"
AzCopyVerbLogin AzCopyVerb = "login"
AzCopyVerbLogout AzCopyVerb = "logout"
AzCopyVerbJobs AzCopyVerb = "jobs"
AzCopyVerbJobsResume AzCopyVerb = "resume"
)

type AzCopyTarget struct {
@@ -321,6 +322,12 @@ func RunAzCopy(a ScenarioAsserter, commandSpec AzCopyCommand) (AzCopyStdout, *Az
out = &AzCopyParsedListStdout{}
case commandSpec.Verb == AzCopyVerbJobs && len(commandSpec.PositionalArgs) != 0 && commandSpec.PositionalArgs[0] == "list":
out = &AzCopyParsedJobsListStdout{}
case commandSpec.Verb == AzCopyVerbJobs && len(commandSpec.PositionalArgs) != 0 && commandSpec.PositionalArgs[0] == "resume":
out = &AzCopyParsedCopySyncRemoveStdout{ // Resume command treated the same as copy/sync/remove
JobPlanFolder: *commandSpec.Environment.JobPlanLocation,
LogFolder: *commandSpec.Environment.LogLocation,
}

default: // We don't know how to parse this.
out = &AzCopyRawStdout{}
}
@@ -346,11 +353,19 @@ func RunAzCopy(a ScenarioAsserter, commandSpec AzCopyCommand) (AzCopyStdout, *Az
}

err = command.Wait()

a.Assert("wait for finalize", common.Iff[Assertion](commandSpec.ShouldFail, Not{IsNil{}}, IsNil{}), err)
a.Assert("expected exit code",
common.Iff[Assertion](commandSpec.ShouldFail, Not{Equal{}}, Equal{}),
0, command.ProcessState.ExitCode())

if err != nil {
a.Log("ShouldFail: Command execution failed with error: %v", err)
} else {
a.Log("ShouldFail: Command executed successfully")
}
a.Log("ShouldFail: Expected exit code: %d, Actual exit code: %d", 0, command.ProcessState.ExitCode())

// validate log file retention for jobs clean command before the job logs are cleaned up and uploaded
if !a.Failed() && len(commandSpec.PositionalArgs) != 0 && commandSpec.PositionalArgs[0] == "clean" {
ValidateLogFileRetention(a, *commandSpec.Environment.LogLocation, 1)
9 changes: 9 additions & 0 deletions e2etest/newe2e_task_runazcopy_login_logout.go
Original file line number Diff line number Diff line change
@@ -69,6 +69,15 @@ func RunAzCopyLoginLogout(a Asserter, verb AzCopyVerb) AzCopyStdout {
}

err = command.Wait()

err = command.Wait()
if err != nil {
a.Log("Login/ Logout: Command execution failed with error: %v", err)
} else {
a.Log("Login/Logout: Command executed successfully")
}
a.Log("Login/out: Expected exit code: %d, Actual exit code: %d", 0, command.ProcessState.ExitCode())

a.Assert("wait for finalize", IsNil{}, err)
a.Assert("expected exit code", Equal{}, 0, command.ProcessState.ExitCode())

93 changes: 69 additions & 24 deletions e2etest/zt_newe2e_file_test.go
Original file line number Diff line number Diff line change
@@ -547,52 +547,97 @@ func (s *FileTestSuite) Scenario_CopyTrailingDotUnsafeDestination(svm *ScenarioV
}, false)
}

// Test empty files are not uploaded when File share quota is hit
// Test:
// - correct number of non-empty files are uploaded when file share quota is hit
// - transfers complete successfully with resume command after increasing quota
func (s *FileTestSuite) Scenario_UploadFilesWithQuota(svm *ScenarioVariationManager) {
quotaMB := int32(10) // 10 MB quota
shareName := "testsharewithquota"
quotaGB := int32(1) // 1 GB quota
shareResource := CreateResource[ContainerResourceManager](svm, GetRootResource(svm, common.ELocation.File()), ResourceDefinitionContainer{
ContainerName: &shareName,
//ContainerName: &shareName,
Properties: ContainerProperties{
FileContainerProperties: FileContainerProperties{
Quota: &quotaMB},
Quota: &quotaGB},
},
})
svm.Assert("Quota is 1GB", Equal{Deep: true},
DerefOrZero(shareResource.GetProperties(svm).FileContainerProperties.Quota), int32(1))

fileSizeMB := int64(6)
fileNames := []string{"file_1.txt", "file_2.txt", "file_3.txt"}
fileSizeGB := int64(1) // Fits one file
fileNames := []string{"file_1.txt", "file_2.txt"}

// Create src obj mapping
srcObjs := make(ObjectResourceMappingFlat)
// Creat source files

// Create source files
for _, fileName := range fileNames {
body := NewRandomObjectContentContainer(fileSizeMB * common.MegaByte)
body := NewRandomObjectContentContainer(fileSizeGB * common.GigaByte)
obj := ResourceDefinitionObject{
ObjectName: &fileName,
Body: body,
}
srcObjs[fileName] = obj
}

for _, fileName := range fileNames {
srcObj := CreateResource[ObjectResourceManager](svm, GetRootResource(svm, common.ELocation.Local()), srcObjs[fileName])
dstObj := shareResource.GetObject(svm, fileName, common.EEntityType.File())
srcContainer := CreateResource[ContainerResourceManager](svm, GetRootResource(svm, common.ELocation.Local()),
ResourceDefinitionContainer{Objects: srcObjs})

// Upload all files
RunAzCopy(svm, AzCopyCommand{
Verb: AzCopyVerbCopy,
Targets: []ResourceManager{srcObj, dstObj},
Flags: CopyFlags{
CopySyncCommonFlags: CopySyncCommonFlags{
Recursive: pointerTo(true),
BlockSizeMB: pointerTo(4.0),
},
stdOut, _ := RunAzCopy(svm, AzCopyCommand{
Verb: AzCopyVerbCopy,
Targets: []ResourceManager{srcContainer, shareResource},
Flags: CopyFlags{
CopySyncCommonFlags: CopySyncCommonFlags{
Recursive: pointerTo(true),
},
})
}
},
ShouldFail: true,
})

// Validate uploaded files are not empty
// Error catchers for full file share
ValidateContainsError(svm, stdOut, []string{"Increase the file share quota and call Resume command."})
ValidateMessageOutput(svm, stdOut, "Increase the file share quota and call Resume command.")

// Validate single uploaded file is not empty
ValidateResource[ContainerResourceManager](svm, shareResource, ResourceDefinitionContainer{
Objects: srcObjs,
}, true)

fileMap := shareResource.ListObjects(svm, "", true)
svm.Assert("Only one file should upload within the quota", Equal{}, len(fileMap)-1, 1)

// Increase quota to fit all files
newQuota := int32(2)
if resourceManager, ok := shareResource.(*FileShareResourceManager); ok {
resourceManager.SetProperties(svm, &ContainerProperties{
FileContainerProperties: FileContainerProperties{
Quota: &newQuota}})
}

// Validate correctly SetProperties updates quota. Prevent nil deref in dry runs
svm.Assert("Quota should be updated", Equal{},
DerefOrZero(shareResource.GetProperties(svm).FileContainerProperties.Quota),
newQuota)

var jobId string
if parsedOut, ok := stdOut.(*AzCopyParsedCopySyncRemoveStdout); ok {
if parsedOut.InitMsg.JobID != "" {
jobId = parsedOut.InitMsg.JobID
}
} else {
// Will enter during dry runs
fmt.Println("failed to cast to AzCopyParsedCopySyncRemoveStdout")
}

RunAzCopy(svm, AzCopyCommand{ // Resume job with same source and dest targets
Verb: AzCopyVerbJobs,
PositionalArgs: []string{"resume", jobId},
ShouldFail: false,
})

// Validate all files are uploaded
fileMapResume := shareResource.ListObjects(svm, "", true)
svm.Assert("All files should be successfully uploaded after quota increase",
Equal{}, len(fileMapResume), 2)

// Validate uploaded files are not empty
ValidateResource[ContainerResourceManager](svm, shareResource, ResourceDefinitionContainer{}, true)
}
2 changes: 1 addition & 1 deletion e2etest/zt_newe2e_jobs_list_test.go
Original file line number Diff line number Diff line change
@@ -16,5 +16,5 @@ func (s *JobsListSuite) Scenario_JobsListBasic(svm *ScenarioVariationManager) {
Stdout: &AzCopyParsedJobsListStdout{},
Flags: ListFlags{},
})
ValidateJobsListOutput(svm, jobsListOutput, 0)
ValidateJobsListOutput(svm, jobsListOutput, -1)
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -62,20 +62,30 @@ require (
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/google/gops v0.3.28 // indirect
github.com/google/s2a-go v0.1.8 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil/v3 v3.23.7 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
@@ -94,6 +104,7 @@ require (
google.golang.org/grpc/stats/opentelemetry v0.0.0-20240907200651-3ffb98b2c93a // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/goversion v1.2.0 // indirect
)

go 1.23.1
Loading

0 comments on commit 9ef35d5

Please sign in to comment.