func main() { configs := createConfigsModelFromEnvs() fmt.Println() configs.print() if err := configs.validate(); err != nil { log.Error("Issue with input: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // // build fmt.Println() log.Info("Building all iOS Xamarin UITest and Referred Projects in solution: %s", configs.XamarinSolution) builder, err := builder.New(configs.XamarinSolution, []constants.ProjectType{constants.ProjectTypeIOS}, false) if err != nil { log.Error("Failed to create xamarin builder, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } callback := func(solutionName string, projectName string, projectType constants.ProjectType, commandStr string, alreadyPerformed bool) { fmt.Println() if projectType == constants.ProjectTypeXamarinUITest { log.Info("Building test project: %s", projectName) } else { log.Info("Building project: %s", projectName) } log.Done("$ %s", commandStr) if alreadyPerformed { log.Warn("build command already performed, skipping...") } fmt.Println() } warnings, err := builder.BuildAllXamarinUITestAndReferredProjects(configs.XamarinConfiguration, configs.XamarinPlatform, nil, callback) for _, warning := range warnings { log.Warn(warning) } if err != nil { log.Error("Build failed, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } projectOutputMap, err := builder.CollectProjectOutputs(configs.XamarinConfiguration, configs.XamarinPlatform) if err != nil { log.Error("Failed to collect project outputs, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } testProjectOutputMap, warnings, err := builder.CollectXamarinUITestProjectOutputs(configs.XamarinConfiguration, configs.XamarinPlatform) for _, warning := range warnings { log.Warn(warning) } if err != nil { log.Error("Failed to collect test project output, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // --- // // Test Cloud submit solutionDir := filepath.Dir(configs.XamarinSolution) pattern := filepath.Join(solutionDir, "packages/Xamarin.UITest.*/tools/test-cloud.exe") testClouds, err := filepath.Glob(pattern) if err != nil { log.Error("Failed to find test-cloud.exe path with pattern (%s), error: %s", pattern, err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } if len(testClouds) == 0 { if err != nil { log.Error("No test-cloud.exe found path with pattern (%s)", pattern) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } } testCloud, err := testcloud.NewModel(testClouds[0]) if err != nil { log.Error("Failed to create test cloud model, error: %s", err) os.Exit(1) } testCloud.SetAPIKey(configs.APIKey) testCloud.SetUser(configs.User) testCloud.SetDevices(configs.Devices) testCloud.SetIsAsyncJSON(configs.IsAsync == "yes") testCloud.SetSeries(configs.Series) // If test cloud runs in asnyc mode test result will not be saved into file resultLogPth := filepath.Join(configs.DeployDir, "TestResult.xml") if configs.IsAsync != "yes" { testCloud.SetNunitXMLPth(resultLogPth) } // Parallelization if configs.Parallelization != "none" { parallelization, err := testcloud.ParseParallelization(configs.Parallelization) if err != nil { log.Error("Failed to parse parallelization, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } testCloud.SetParallelization(parallelization) } // --- // Custom Options if configs.CustomOptions != "" { options, err := shellquote.Split(configs.CustomOptions) if err != nil { log.Error("Failed to split params (%s), error: %s", configs.CustomOptions, err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } testCloud.SetCustomOptions(options...) } // --- // Artifacts resultLog := "" for testProjectName, testProjectOutput := range testProjectOutputMap { if len(testProjectOutput.ReferredProjectNames) == 0 { log.Warn("Test project (%s) does not refers to any project, skipping...", testProjectName) continue } for _, projectName := range testProjectOutput.ReferredProjectNames { projectOutput, ok := projectOutputMap[projectName] if !ok { continue } ipaPth := "" dsymPth := "" for _, output := range projectOutput.Outputs { if output.OutputType == constants.OutputTypeIPA { ipaPth = output.Pth } if output.OutputType == constants.OutputTypeDSYM { dsymPth = output.Pth } } if ipaPth == "" { log.Warn("No ipa generated for project: %s", projectName) } if dsymPth == "" { log.Warn("No dsym generated for project: %s", projectName) } // Submit fmt.Println() log.Info("Testing (%s) against (%s)", testProjectName, projectName) log.Detail("test dll: %s", testProjectOutput.Output.Pth) log.Detail("ipa: %s", ipaPth) log.Detail("dsym: %s", dsymPth) testCloud.SetAssemblyDir(filepath.Dir(testProjectOutput.Output.Pth)) testCloud.SetIPAPth(ipaPth) testCloud.SetDSYMPth(dsymPth) fmt.Println() log.Info("Submitting:") log.Done("$ %s", testCloud.PrintableCommand()) lines := []string{} callback := func(line string) { log.Detail(line) lines = append(lines, line) } err := testCloud.Submit(callback) // If test cloud runs in asnyc mode test result will not be saved into file if configs.IsAsync != "yes" { testLog, logErr := testResultLogContent(resultLogPth) if logErr != nil { log.Warn("Failed to read test result, error: %s", logErr) } resultLog = testLog } if err != nil { log.Error("Submit failed, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } if resultLog != "" { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", resultLog); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", err) } } os.Exit(1) } // --- if configs.IsAsync == "yes" { fmt.Println() log.Info("Preocessing json result:") jsonLine := "" for _, line := range lines { if strings.HasPrefix(line, "{") && strings.HasSuffix(line, "}") { jsonLine = line } } if jsonLine != "" { var result JSONResultModel if err := json.Unmarshal([]byte(jsonLine), &result); err != nil { log.Error("Failed to unmarshal result, error: %s", err) } else { for _, errorMsg := range result.ErrorMessages { log.Error(errorMsg) } if len(result.ErrorMessages) > 0 { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } if resultLog != "" { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", resultLog); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", err) } } os.Exit(1) } if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_TO_RUN_ID", result.TestRunID); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_TO_RUN_ID", err) } log.Done("TestRunId (%s) is available in (%s) environment variable", result.TestRunID, "BITRISE_XAMARIN_TEST_TO_RUN_ID") } } } } } // --- if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "succeeded"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } if resultLog != "" { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", resultLog); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", err) } } }
func main() { configs := createConfigsModelFromEnvs() fmt.Println() configs.print() if err := configs.validate(); err != nil { log.Error("Issue with input: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // Get Simulator Infos fmt.Println() log.Info("Collecting simulator info...") simulatorInfo, err := getSimulatorInfo(configs.SimulatorOsVersion, configs.SimulatorDevice) if err != nil { log.Error("Failed to get simulator infos, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } log.Done("Simulator (%s), id: (%s), status: %s", simulatorInfo.Name, simulatorInfo.ID, simulatorInfo.Status) // --- // Nunit Console path nunitConsolePth, err := nunit.SystemNunit3ConsolePath() if err != nil { log.Error("Failed to get system insatlled nunit3-console.exe path, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // --- // // build fmt.Println() log.Info("Building all iOS Xamarin UITest and Referred Projects in solution: %s", configs.XamarinSolution) builder, err := builder.New(configs.XamarinSolution, []constants.ProjectType{constants.ProjectTypeIOS}, false) if err != nil { log.Error("Failed to create xamarin builder, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } callback := func(solutionName string, projectName string, projectType constants.ProjectType, commandStr string, alreadyPerformed bool) { fmt.Println() if projectType == constants.ProjectTypeXamarinUITest { log.Info("Building test project: %s", projectName) } else { log.Info("Building project: %s", projectName) } log.Done("$ %s", commandStr) if alreadyPerformed { log.Warn("build command already performed, skipping...") } fmt.Println() } warnings, err := builder.BuildAllXamarinUITestAndReferredProjects(configs.XamarinConfiguration, configs.XamarinPlatform, nil, callback) for _, warning := range warnings { log.Warn(warning) } if err != nil { log.Error("Build failed, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } projectOutputMap, err := builder.CollectProjectOutputs(configs.XamarinConfiguration, configs.XamarinPlatform) if err != nil { log.Error("Failed to collect project outputs, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } testProjectOutputMap, warnings, err := builder.CollectXamarinUITestProjectOutputs(configs.XamarinConfiguration, configs.XamarinPlatform) for _, warning := range warnings { log.Warn(warning) } if err != nil { log.Error("Failed to collect test project output, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // --- // // Run nunit tests nunitConsole, err := nunit.New(nunitConsolePth) if err != nil { log.Error("Failed to create nunit console model, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } resultLogPth := filepath.Join(configs.DeployDir, "TestResult.xml") nunitConsole.SetResultLogPth(resultLogPth) // Artifacts resultLog := "" for testProjectName, testProjectOutput := range testProjectOutputMap { if len(testProjectOutput.ReferredProjectNames) == 0 { log.Warn("Test project (%s) does not refers to any project, skipping...", testProjectName) continue } for _, projectName := range testProjectOutput.ReferredProjectNames { projectOutput, ok := projectOutputMap[projectName] if !ok { continue } appPth := "" for _, output := range projectOutput.Outputs { if output.OutputType == constants.OutputTypeAPP { appPth = output.Pth } } if appPth == "" { log.Error("No app generated for project: %s", projectName) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // Set APP_BUNDLE_PATH env to let the test know which .app file should be tested // This env is used in the Xamarin.UITest project to refer to the .app path if err := os.Setenv("APP_BUNDLE_PATH", appPth); err != nil { log.Error("Failed to set APP_BUNDLE_PATH environment, without this env test will fail, error: %s", err) if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } os.Exit(1) } // Run test fmt.Println() log.Info("Testing (%s) against (%s)", testProjectName, projectName) log.Detail("test dll: %s", testProjectOutput.Output.Pth) log.Detail("app: %s", appPth) nunitConsole.SetDLLPth(testProjectOutput.Output.Pth) nunitConsole.SetTestToRun(configs.TestToRun) fmt.Println() log.Info("Running Xamarin UITest") log.Done("$ %s", nunitConsole.PrintableCommand()) fmt.Println() err := nunitConsole.Run() testLog, readErr := testResultLogContent(resultLogPth) if readErr != nil { log.Warn("Failed to read test result, error: %s", readErr) } resultLog = testLog if err != nil { log.Error("Test failed, error: %s", err) if errorMsg, err := parseErrorFromResultLog(resultLog); err != nil { log.Warn("Failed to parse error message from result log, error: %s", err) } else if errorMsg != "" { log.Error("%s", errorMsg) } if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "failed"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } if resultLog != "" { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", resultLog); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", err) } } os.Exit(1) } } } if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "succeeded"); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err) } if resultLog != "" { if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", resultLog); err != nil { log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_FULL_RESULTS_TEXT", err) } } }