diff --git a/test/v200/apiTest/api_test.go b/test/v200/apiTest/api_test.go index f94b0bde2..a39126a3f 100644 --- a/test/v200/apiTest/api_test.go +++ b/test/v200/apiTest/api_test.go @@ -66,6 +66,24 @@ func Test_MultiComponent(t *testing.T) { apiUtils.RunTest(testContent, t) } +func Test_Projects(t *testing.T) { + testContent := commonUtils.TestContent{} + testContent.ProjectTypes = []schema.ProjectSourceType{ + schema.GitProjectSourceType, + schema.ZipProjectSourceType} + testContent.FileName = commonUtils.GetDevFileName() + apiUtils.RunTest(testContent, t) +} + +func Test_StarterProjects(t *testing.T) { + testContent := commonUtils.TestContent{} + testContent.StarterProjectTypes = []schema.ProjectSourceType{ + schema.GitProjectSourceType, + schema.ZipProjectSourceType} + testContent.FileName = commonUtils.GetDevFileName() + apiUtils.RunTest(testContent, t) +} + func Test_Everything(t *testing.T) { testContent := commonUtils.TestContent{} testContent.CommandTypes = []schema.CommandType{ @@ -75,6 +93,12 @@ func Test_Everything(t *testing.T) { testContent.ComponentTypes = []schema.ComponentType{ schema.ContainerComponentType, schema.VolumeComponentType} + testContent.ProjectTypes = []schema.ProjectSourceType{ + schema.GitProjectSourceType, + schema.ZipProjectSourceType} + testContent.StarterProjectTypes = []schema.ProjectSourceType{ + schema.GitProjectSourceType, + schema.ZipProjectSourceType} testContent.FileName = commonUtils.GetDevFileName() apiUtils.RunTest(testContent, t) } diff --git a/test/v200/utils/common/project_test_utils.go b/test/v200/utils/common/project_test_utils.go new file mode 100644 index 000000000..0666ccb88 --- /dev/null +++ b/test/v200/utils/common/project_test_utils.go @@ -0,0 +1,210 @@ +package common + +import ( + "fmt" + schema "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" +) + +// projectAdded adds a new project to the test schema data and notifies the follower +func (testDevfile *TestDevfile) projectAdded(project schema.Project) { + LogInfoMessage(fmt.Sprintf("project added Name: %s", project.Name)) + testDevfile.SchemaDevFile.Projects = append(testDevfile.SchemaDevFile.Projects, project) + if testDevfile.Follower != nil { + testDevfile.Follower.AddProject(project) + } +} + +// projectUpdated notifies the follower of the project which has been updated +func (testDevfile *TestDevfile) projectUpdated(project schema.Project) { + LogInfoMessage(fmt.Sprintf("project updated Name: %s", project.Name)) + testDevfile.replaceSchemaProject(project) + if testDevfile.Follower != nil { + testDevfile.Follower.UpdateProject(project) + } +} + +// starterProjectAdded adds a new starter project to the test schema data and notifies the follower +func (testDevfile *TestDevfile) starterProjectAdded(starterProject schema.StarterProject) { + LogInfoMessage(fmt.Sprintf("starter project added Name: %s", starterProject.Name)) + testDevfile.SchemaDevFile.StarterProjects = append(testDevfile.SchemaDevFile.StarterProjects, starterProject) + if testDevfile.Follower != nil { + testDevfile.Follower.AddStarterProject(starterProject) + } +} + +// starterProjectUpdated notifies the follower of the starter project which has been updated +func (testDevfile *TestDevfile) starterProjectUpdated(starterProject schema.StarterProject) { + LogInfoMessage(fmt.Sprintf("starter project updated Name: %s", starterProject.Name)) + testDevfile.replaceSchemaStarterProject(starterProject) + if testDevfile.Follower != nil { + testDevfile.Follower.UpdateStarterProject(starterProject) + } +} + +// replaceSchemaProject replaces a Project in the saved devfile schema structure +func (testDevfile *TestDevfile) replaceSchemaProject(project schema.Project) { + for i := 0; i < len(testDevfile.SchemaDevFile.Projects); i++ { + if testDevfile.SchemaDevFile.Projects[i].Name == project.Name { + testDevfile.SchemaDevFile.Projects[i] = project + break + } + } +} + +// replaceSchemaStarterProject replaces a Starter Project in the saved devfile schema structure +func (testDevfile *TestDevfile) replaceSchemaStarterProject(starterProject schema.StarterProject) { + for i := 0; i < len(testDevfile.SchemaDevFile.StarterProjects); i++ { + if testDevfile.SchemaDevFile.StarterProjects[i].Name == starterProject.Name { + testDevfile.SchemaDevFile.StarterProjects[i] = starterProject + break + } + } +} + +// getRemotes creates and returns a map of remotes +func getRemotes(numRemotes int) map[string]string { + remotes := make(map[string]string) + for i := 0; i < numRemotes; i++ { + key := GetRandomUniqueString(GetRandomNumber(6, 12), false) + remotes[key] = GetRandomUniqueString(GetRandomNumber(6, 12), false) + LogInfoMessage(fmt.Sprintf("Set remote key= %s, value= %s", key, remotes[key])) + } + return remotes +} + +// AddProject adds a project of the specified type, with random attributes, to the devfile schema +func (testDevfile *TestDevfile) AddProject(projectType schema.ProjectSourceType) string { + project := testDevfile.createProject(projectType) + testDevfile.SetProjectValues(&project) + return project.Name +} + +// AddStarterProject adds a starter project of the specified type, with random attributes, to the devfile schema +func (testDevfile *TestDevfile) AddStarterProject(projectType schema.ProjectSourceType) string { + starterProject := testDevfile.createStarterProject(projectType) + testDevfile.SetStarterProjectValues(&starterProject) + return starterProject.Name +} + +// createProject creates a project of a specified type with only required attributes set +func (testDevfile *TestDevfile) createProject(projectType schema.ProjectSourceType) schema.Project { + project := schema.Project{} + project.Name = GetRandomUniqueString(GetRandomNumber(8, 63), true) + LogInfoMessage(fmt.Sprintf("Create Project Name: %s", project.Name)) + + if projectType == schema.GitProjectSourceType { + project.Git = createGitProject(GetRandomNumber(1, 5)) + } else if projectType == schema.ZipProjectSourceType { + project.Zip = createZipProject() + } + testDevfile.projectAdded(project) + return project +} + +// createStarterProject creates a starter project of a specified type with only required attributes set +func (testDevfile *TestDevfile) createStarterProject(projectType schema.ProjectSourceType) schema.StarterProject { + starterProject := schema.StarterProject{} + starterProject.Name = GetRandomUniqueString(GetRandomNumber(8, 63), true) + LogInfoMessage(fmt.Sprintf("Create StarterProject Name: %s", starterProject.Name)) + + if projectType == schema.GitProjectSourceType { + starterProject.Git = createGitProject(1) + } else if projectType == schema.ZipProjectSourceType { + starterProject.Zip = createZipProject() + } + testDevfile.starterProjectAdded(starterProject) + return starterProject + +} + +// createGitProject creates a git project structure with mandatory attributes set +func createGitProject(numRemotes int) *schema.GitProjectSource { + project := schema.GitProjectSource{} + project.Remotes = getRemotes(numRemotes) + return &project +} + +// createZipProject creates a zip project structure +func createZipProject() *schema.ZipProjectSource { + project := schema.ZipProjectSource{} + return &project +} + +// SetProjectValues sets project attributes, common to all projects, to random values. +func (testDevfile *TestDevfile) SetProjectValues(project *schema.Project) { + + if GetBinaryDecision() { + project.ClonePath = "./" + GetRandomString(GetRandomNumber(4, 12), false) + LogInfoMessage(fmt.Sprintf("Set ClonePath : %s", project.ClonePath)) + } + + if GetBinaryDecision() { + var sparseCheckoutDirs []string + numDirs := GetRandomNumber(1, 6) + for i := 0; i < numDirs; i++ { + sparseCheckoutDirs = append(sparseCheckoutDirs, GetRandomString(8, false)) + LogInfoMessage(fmt.Sprintf("Set sparseCheckoutDir : %s", sparseCheckoutDirs[i])) + } + project.SparseCheckoutDirs = sparseCheckoutDirs + } + + if project.Git != nil { + setGitProjectValues(project.Git) + } else if project.Zip != nil { + setZipProjectValues(project.Zip) + } + + testDevfile.projectUpdated(*project) +} + +// SetStarterProjectValues sets starter project attributes, common to all starter projects, to random values. +func (testDevfile *TestDevfile) SetStarterProjectValues(starterProject *schema.StarterProject) { + + if GetBinaryDecision() { + numWords := GetRandomNumber(2, 6) + for i := 0; i < numWords; i++ { + if i > 0 { + starterProject.Description += " " + } + starterProject.Description += GetRandomString(8, false) + } + LogInfoMessage(fmt.Sprintf("Set Description : %s", starterProject.Description)) + } + + if GetBinaryDecision() { + starterProject.SubDir = GetRandomString(12, false) + LogInfoMessage(fmt.Sprintf("Set SubDir : %s", starterProject.SubDir)) + } + + if starterProject.Git != nil { + setGitProjectValues(starterProject.Git) + } else if starterProject.Zip != nil { + setZipProjectValues(starterProject.Zip) + } + + testDevfile.starterProjectUpdated(*starterProject) + +} + +// setGitProjectValues randomly sets attributes for a Git project +func setGitProjectValues(gitProject *schema.GitProjectSource) { + + if len(gitProject.Remotes) > 1 { + numKey := GetRandomNumber(1, len(gitProject.Remotes)) + for key, _ := range gitProject.Remotes { + numKey-- + if numKey <= 0 { + gitProject.CheckoutFrom = &schema.CheckoutFrom{} + gitProject.CheckoutFrom.Remote = key + gitProject.CheckoutFrom.Revision = GetRandomString(8, false) + LogInfoMessage(fmt.Sprintf("set CheckoutFrom remote = %s, and revision = %s", gitProject.CheckoutFrom.Remote, gitProject.CheckoutFrom.Revision)) + break + } + } + } +} + +// setZipProjectValues randomly sets attributes for a Zip Project +func setZipProjectValues(zipProject *schema.ZipProjectSource) { + zipProject.Location = GetRandomString(GetRandomNumber(8, 16), false) +} diff --git a/test/v200/utils/common/test_utils.go b/test/v200/utils/common/test_utils.go index e53ea473c..ba8c2ce01 100644 --- a/test/v200/utils/common/test_utils.go +++ b/test/v200/utils/common/test_utils.go @@ -21,6 +21,10 @@ const ( maxCommands = 10 // maxComponents : The maximum number of components to include in a generated devfile maxComponents = 10 + // maxProjects : The maximum number of projects to include in a generated devfile + maxProjects = 10 + // maxStarterProjects : the number of starterProjects to create for each test + maxStarterProjects = 10 defaultTempDir = "./tmp/" logFileName = "test.log" @@ -61,10 +65,12 @@ type DevfileValidator interface { // TestContent - structure used by a test to configure the tests to run type TestContent struct { - CommandTypes []schema.CommandType - ComponentTypes []schema.ComponentType - FileName string - EditContent bool + CommandTypes []schema.CommandType + ComponentTypes []schema.ComponentType + ProjectTypes []schema.ProjectSourceType + StarterProjectTypes []schema.ProjectSourceType + FileName string + EditContent bool } // init creates: @@ -152,7 +158,7 @@ func LogMessage(message string) string { return message } -var errorPrefix = "..... ERROR : " +var errorPrefix = "..... ERROR :" var infoPrefix = "INFO :" // LogErrorMessage logs the specified message as an error message and returns the message logged @@ -185,7 +191,11 @@ var StringCount int = 0 // If lower is set to true a lower case string is returned. func GetRandomUniqueString(n int, lower bool) string { StringCount++ - return fmt.Sprintf("%s%04d", GetRandomString(n, lower), StringCount) + countAsString := fmt.Sprintf("%05d", StringCount) + if n < len(countAsString) { + n += len(countAsString) + } + return fmt.Sprintf("%s%s", GetRandomString(n-len(countAsString), lower), countAsString) } const schemaBytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" @@ -270,6 +280,22 @@ func (testDevfile *TestDevfile) RunTest(testContent TestContent, t *testing.T) { } } + if len(testContent.ProjectTypes) > 0 { + numProjects := GetRandomNumber(1, maxProjects) + for i := 0; i < numProjects; i++ { + projectIndex := GetRandomNumber(1, len(testContent.ProjectTypes)) + testDevfile.AddProject(testContent.ProjectTypes[projectIndex-1]) + } + } + + if len(testContent.StarterProjectTypes) > 0 { + numStarterProjects := GetRandomNumber(1, maxStarterProjects) + for i := 0; i < numStarterProjects; i++ { + starterProjectIndex := GetRandomNumber(1, len(testContent.StarterProjectTypes)) + testDevfile.AddStarterProject(testContent.StarterProjectTypes[starterProjectIndex-1]) + } + } + err := testDevfile.Validator.WriteAndValidate(testDevfile) if err != nil { t.Fatalf(LogErrorMessage(fmt.Sprintf("ERROR verifying devfile : %s : %v", testContent.FileName, err)))