func (a *Archive) getArchive() (string, error) { a.Do(func() { a.path, a.err = remote.CreateTestArchive() }) return a.path, a.err }
func main() { flag.Parse() rand.Seed(time.Now().UTC().UnixNano()) if *buildOnly { // Build the archive and exit remote.CreateTestArchive() return } if *hosts == "" && *imageConfigFile == "" && *images == "" { glog.Fatalf("Must specify one of --image-config-file, --hosts, --images.") } var err error computeService, err = getComputeClient() if err != nil { glog.Fatalf("Unable to create gcloud compute service using defaults. Make sure you are authenticated. %v", err) } gceImages := &internalImageConfig{ images: make(map[string]internalGCEImage), } if *imageConfigFile != "" { // parse images imageConfigData, err := ioutil.ReadFile(*imageConfigFile) if err != nil { glog.Fatalf("Could not read image config file provided: %v", err) } externalImageConfig := ImageConfig{Images: make(map[string]GCEImage)} err = yaml.Unmarshal(imageConfigData, &externalImageConfig) if err != nil { glog.Fatalf("Could not parse image config file: %v", err) } for shortName, imageConfig := range externalImageConfig.Images { var images []string isRegex, name := false, shortName if imageConfig.ImageRegex != "" && imageConfig.Image == "" { isRegex = true images, err = getGCEImages(imageConfig.ImageRegex, imageConfig.Project, imageConfig.PreviousImages) if err != nil { glog.Fatalf("Could not retrieve list of images based on image prefix %q: %v", imageConfig.ImageRegex, err) } } else { images = []string{imageConfig.Image} } for _, image := range images { gceImage := internalGCEImage{ image: image, project: imageConfig.Project, metadata: getImageMetadata(imageConfig.Metadata), machine: imageConfig.Machine, tests: imageConfig.Tests, } if isRegex { name = shortName + "-" + image } gceImages.images[name] = gceImage } } } // Allow users to specify additional images via cli flags for local testing // convenience; merge in with config file if *images != "" { if *imageProject == "" { glog.Fatal("Must specify --image-project if you specify --images") } cliImages := strings.Split(*images, ",") for _, img := range cliImages { gceImage := internalGCEImage{ image: img, project: *imageProject, metadata: getImageMetadata(*instanceMetadata), } gceImages.images[img] = gceImage } } if len(gceImages.images) != 0 && *zone == "" { glog.Fatal("Must specify --zone flag") } for shortName, image := range gceImages.images { if image.project == "" { glog.Fatalf("Invalid config for %v; must specify a project", shortName) } } if len(gceImages.images) != 0 { if *project == "" { glog.Fatal("Must specify --project flag to launch images into") } } if *instanceNamePrefix == "" { *instanceNamePrefix = "tmp-node-e2e-" + uuid.NewUUID().String()[:8] } // Setup coloring stat, _ := os.Stdout.Stat() useColor := (stat.Mode() & os.ModeCharDevice) != 0 blue := "" noColour := "" if useColor { blue = "\033[0;34m" noColour = "\033[0m" } go arc.getArchive() defer arc.deleteArchive() results := make(chan *TestResult) running := 0 for shortName := range gceImages.images { imageConfig := gceImages.images[shortName] fmt.Printf("Initializing e2e tests using image %s.\n", shortName) running++ go func(image *internalGCEImage, junitFilePrefix string) { results <- testImage(image, junitFilePrefix) }(&imageConfig, shortName) } if *hosts != "" { for _, host := range strings.Split(*hosts, ",") { fmt.Printf("Initializing e2e tests using host %s.\n", host) running++ go func(host string, junitFilePrefix string) { results <- testHost(host, *cleanup, junitFilePrefix, *setupNode, *ginkgoFlags) }(host, host) } } // Wait for all tests to complete and emit the results errCount := 0 exitOk := true for i := 0; i < running; i++ { tr := <-results host := tr.host fmt.Println() // Print an empty line fmt.Printf("%s>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>%s\n", blue, noColour) fmt.Printf("%s> START TEST >%s\n", blue, noColour) fmt.Printf("%s>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>%s\n", blue, noColour) fmt.Printf("Start Test Suite on Host %s\n", host) fmt.Printf("%s\n", tr.output) if tr.err != nil { errCount++ fmt.Printf("Failure Finished Test Suite on Host %s\n%v\n", host, tr.err) } else { fmt.Printf("Success Finished Test Suite on Host %s\n", host) } exitOk = exitOk && tr.exitOk fmt.Printf("%s<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<%s\n", blue, noColour) fmt.Printf("%s< FINISH TEST <%s\n", blue, noColour) fmt.Printf("%s<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<%s\n", blue, noColour) fmt.Println() // Print an empty line } // Set the exit code if there were failures if !exitOk { fmt.Printf("Failure: %d errors encountered.\n", errCount) callGubernator(*gubernator) os.Exit(1) } callGubernator(*gubernator) }