func main()

in cmd/manager/main.go [130:474]


func main() {
	flag.Parse()
	if *project == "" || *zone == "" || *images == "" {
		log.Fatal("Must provide project, zone and images arguments")
		return
	}
	var testProjectsReal []string
	if *testProjects == "" {
		testProjectsReal = append(testProjectsReal, *project)
	} else {
		testProjectsReal = strings.Split(*testProjects, ",")
	}

	log.Printf("Running in project %s zone %s. Tests will run in projects: %s", *project, *zone, testProjectsReal)
	if *gcsPath != "" {
		log.Printf("gcs_path set to %s", *gcsPath)
	}

	var filterRegex *regexp.Regexp
	if *filter != "" {
		var err error
		filterRegex, err = regexp.Compile(*filter)
		if err != nil {
			log.Fatal("-filter flag not valid:", err)
		}
		log.Printf("using -filter %s", *filter)
	}

	var excludeRegex *regexp.Regexp
	if *exclude != "" {
		var err error
		excludeRegex, err = regexp.Compile(*exclude)
		if err != nil {
			log.Fatal("-exclude flag not valid:", err)
		}
		log.Printf("using -exclude %s", *exclude)
	}

	if *testExcludeFilter != "" {
		log.Printf("Using -exclude_discrete_tests %s", *testExcludeFilter)
	}

	if *machineType != "" {
		log.Printf("The -machine_type flag is deprecated, please use -x86_shape and -arm64_shape instead. Retaining legacy behavior while this is set.")
		*x86Shape = *machineType
		*arm64Shape = *machineType
	}

	var reservationURLSlice []string
	if *reservationURLs != "" {
		reservationURLSlice = strings.Split(*reservationURLs, ",")
	}

	// Setup tests.
	testPackages := []struct {
		name      string
		setupFunc func(*imagetest.TestWorkflow) error
	}{
		{
			acceleratorconfig.Name,
			acceleratorconfig.TestSetup,
		},
		{
			acceleratorrdma.Name,
			acceleratorrdma.TestSetup,
		},
		{
			cvm.Name,
			cvm.TestSetup,
		},
		{
			livemigrate.Name,
			livemigrate.TestSetup,
		},
		{
			suspendresume.Name,
			suspendresume.TestSetup,
		},
		{
			networkperf.Name,
			networkperf.TestSetup,
		},

		{
			networkinterfacenaming.Name,
			networkinterfacenaming.TestSetup,
		},
		{
			loadbalancer.Name,
			loadbalancer.TestSetup,
		},
		{
			guestagent.Name,
			guestagent.TestSetup,
		},
		{
			hostnamevalidation.Name,
			hostnamevalidation.TestSetup,
		},
		{
			imageboot.Name,
			imageboot.TestSetup,
		},
		{
			licensevalidation.Name,
			licensevalidation.TestSetup,
		},
		{
			network.Name,
			network.TestSetup,
		},
		{
			security.Name,
			security.TestSetup,
		},
		{
			hotattach.Name,
			hotattach.TestSetup,
		},
		{
			lssd.Name,
			lssd.TestSetup,
		},
		{
			disk.Name,
			disk.TestSetup,
		},
		{
			shapevalidation.Name,
			shapevalidation.TestSetup,
		},
		{
			packagemanager.Name,
			packagemanager.TestSetup,
		},
		{
			packageupgrade.Name,
			packageupgrade.TestSetup,
		},
		{
			packagevalidation.Name,
			packagevalidation.TestSetup,
		},
		{
			storageperf.Name,
			storageperf.TestSetup,
		},
		{
			ssh.Name,
			ssh.TestSetup,
		},
		{
			winrm.Name,
			winrm.TestSetup,
		},
		{
			sql.Name,
			sql.TestSetup,
		},
		{
			metadata.Name,
			metadata.TestSetup,
		},
		{
			oslogin.Name,
			oslogin.TestSetup,
		},
		{
			mdsmtls.Name,
			mdsmtls.TestSetup,
		},
		{
			mdsroutes.Name,
			mdsroutes.TestSetup,
		},
		{
			windowscontainers.Name,
			windowscontainers.TestSetup,
		},
		{
			vmspec.Name,
			vmspec.TestSetup,
		},
		{
			pluginmanager.Name,
			pluginmanager.TestSetup,
		},
		{
			compatmanager.Name,
			compatmanager.TestSetup,
		},
	}

	ctx := context.Background()
	var computeclient compute.Client
	var err error
	if *computeEndpointOverride != "" {
		log.Printf("Using compute endpoint %q", *computeEndpointOverride)
		computeclient, err = compute.NewClient(ctx, option.WithEndpoint(*computeEndpointOverride))
	} else {
		computeclient, err = compute.NewClient(ctx)
	}
	if err != nil {
		log.Fatalf("Could not create compute client:%v", err)
	}

	var testWorkflows []*imagetest.TestWorkflow
	for _, testPackage := range testPackages {
		if filterRegex != nil && !filterRegex.MatchString(testPackage.name) {
			continue
		}
		if excludeRegex != nil && excludeRegex.MatchString(testPackage.name) {
			continue
		}
		for _, image := range strings.Split(*images, ",") {
			if !strings.Contains(image, "/") {
				// Find the project of the image.
				project := ""
				for k := range projectMap {
					if strings.Contains(k, "sap") {
						// sap follows a slightly different naming convention.
						imageName := strings.Split(k, "-")[0]
						if strings.HasPrefix(image, imageName) && strings.Contains(image, "sap") {
							project = projectMap[k]
							break
						}
					}
					if strings.HasPrefix(image, k) {
						project = projectMap[k]
						break
					}
				}
				if project == "" {
					log.Fatalf("unknown image %s", image)
				}

				// Check whether the image is an image family or a specific image version.
				isMatch, err := regexp.MatchString(".*v([0-9]+)", image)
				if err != nil {
					log.Fatalf("failed regex: %v", err)
				}
				if isMatch {
					image = fmt.Sprintf("projects/%s/global/images/%s", project, image)
				} else {
					image = fmt.Sprintf("projects/%s/global/images/family/%s", project, image)
				}
			}

			log.Printf("Add test workflow for test %s on image %s", testPackage.name, image)
			test, err := imagetest.NewTestWorkflow(&imagetest.TestWorkflowOpts{
				Client:                  computeclient,
				ComputeEndpointOverride: *computeEndpointOverride,
				Name:                    testPackage.name,
				Image:                   image,
				Timeout:                 *timeout,
				Project:                 *project,
				Zone:                    *zone,
				ExcludeFilter:           *testExcludeFilter,
				X86Shape:                *x86Shape,
				ARM64Shape:              *arm64Shape,
				UseReservations:         *useReservations,
				ReservationURLs:         reservationURLSlice,
				AcceleratorType:         *acceleratorType,
			})
			if err != nil {
				log.Fatalf("Failed to create test workflow: %v", err)
			}
			testWorkflows = append(testWorkflows, test)
			if err := testPackage.setupFunc(test); err != nil {
				log.Fatalf("%s.TestSetup for %s failed: %v", testPackage.name, image, err)
			}
		}
	}

	if len(testWorkflows) == 0 {
		log.Fatalf("No workflows to run!")
	}

	log.Println("Done with setup")

	storageclient, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatalf("failed to set up storage client: %v", err)
	}

	if *printwf {
		imagetest.PrintTests(ctx, storageclient, testWorkflows, *project, *zone, *gcsPath, *localPath)
		return
	}

	if *validate {
		if err := imagetest.ValidateTests(ctx, storageclient, testWorkflows, *project, *zone, *gcsPath, *localPath); err != nil {
			log.Printf("Validate failed: %v\n", err)
		}
		return
	}

	suites, err := imagetest.RunTests(ctx, storageclient, testWorkflows, *project, *zone, *gcsPath, *localPath, *parallelCount, *parallelStagger, testProjectsReal)
	if err != nil {
		log.Fatalf("Failed to run tests: %v", err)
	}
	if *writeLocalArtifacts != "" {
		var wg sync.WaitGroup
		for _, twf := range testWorkflows {
			bkt := strings.TrimSuffix(strings.TrimPrefix(regexp.MustCompile(`gs://[a-z0-9][a-z0-9-_.]{2,62}[a-z0-9]/?`).FindString(twf.GCSPath), "gs://"), "/")
			if bkt == "" {
				log.Printf("could not find gcs bucket from %s for workflow %s", twf.GCSPath, twf.Name)
				continue
			}
			gcsSubfolder := strings.TrimPrefix(twf.GCSPath, "gs://"+bkt+"/")
			wg.Add(1)
			go func(bucket, folder, dstDir string) {
				defer wg.Done()
				if err := downloadFolder(ctx, storageclient, bucket, folder, dstDir); err != nil {
					log.Printf("failed to download test artifacts from folder %s in bucket %s to %s: %v\n", folder, bucket, dstDir, err)
				}
			}(bkt, gcsSubfolder, *writeLocalArtifacts)
		}
		wg.Wait()
	}

	bytes, err := xml.MarshalIndent(suites, "", "\t")
	if err != nil {
		log.Fatalf("failed to marshall result: %v", err)
	}
	bytes = []byte(fmt.Sprintf("%s%s", xml.Header, bytes))
	var outFile *os.File
	if artifacts := os.Getenv("ARTIFACTS"); artifacts != "" {
		outFile, err = os.Create(artifacts + "/junit.xml")
	} else {
		outFile, err = os.Create(*outPath)
	}
	if err != nil {
		log.Fatalf("failed to create output file: %v", err)
	}
	defer outFile.Close()

	outFile.Write(bytes)
	outFile.Write([]byte{'\n'})
	fmt.Printf("%s\n", bytes)

	if *setExitStatus && (suites.Errors != 0 || suites.Failures != 0) {
		log.Fatalf("test suite has error or failure")
	}
}