// GenerateTestMain returns the source code for a test program that will run // the specified test functions from the specified package. func GenerateTestMain(packageName string, funcs *set.StringSet) string { var funcVec vector.StringVector for val := range funcs.Iter() { funcVec.Push(val) } result := "" result += "package main\n\n" result += "import \"testing\"\n" if funcVec.Len() > 0 { result += fmt.Sprintf("import \"./%s\"\n\n", packageName) } result += "var tests = []testing.Test {\n" for _, val := range funcVec.Data() { result += fmt.Sprintf("\ttesting.Test{\"%s\", %s.%s},\n", val, packageName, val) } result += "}\n\n" result += "func main() {\n" result += "\ttesting.Main(tests)\n" result += "}\n" return result }
func createSet(contents []string) *set.StringSet { var result set.StringSet for _, val := range contents { result.Insert(val) } return &result }
func addDeps(depsMap map[string]*set.StringSet, name string, deps []string) { var set set.StringSet for _, val := range deps { set.Insert(val) } depsMap[name] = &set }
func expectContentsEqual(t *testing.T, set *set.StringSet, expected []string) { var contents vector.StringVector for val := range set.Iter() { contents.Push(val) } sort.SortStrings(contents) sort.SortStrings(expected) if !reflect.DeepEqual(contents.Data(), expected) { t.Errorf("Expected:%v\nGot: %v", expected, contents) } }
// compileFiles invokes 6g with the appropriate arguments for compiling the // supplied set of .go files, and exits the program if the subprocess fails. func compileFiles(files *set.StringSet, targetBaseName string) { compilerName, ok := compilers[os.Getenv("GOARCH")] if !ok { fmt.Println("Could not determine the correct compiler to run.") fmt.Println("Please ensure that $GOARCH is set.") os.Exit(1) } compilerPath := path.Join(os.Getenv("GOBIN"), compilerName) gopackPath := path.Join(os.Getenv("GOBIN"), "gopack") targetDir, _ := path.Split(targetBaseName) if targetDir != "" { os.MkdirAll(path.Join("igo-out", targetDir), 0700) } // Compile var compilerArgs vector.StringVector compilerArgs.Push("-o") compilerArgs.Push(targetBaseName + ".6") for file := range files.Iter() { compilerArgs.Push(path.Join("../", file)) } if !executeCommand(compilerPath, compilerArgs.Data(), "igo-out/") { os.Exit(1) } // Pack var gopackArgs vector.StringVector gopackArgs.Push("grc") gopackArgs.Push(targetBaseName + ".a") gopackArgs.Push(targetBaseName + ".6") if !executeCommand(gopackPath, gopackArgs.Data(), "igo-out/") { os.Exit(1) } }
func main() { flag.Parse() if flag.NArg() != 2 { printUsageAndExit() } command := flag.Arg(0) if command != "build" && command != "test" { printUsageAndExit() } // Grab dependency and file information for every local package, starting // with the specified one. We consider a package local if it starts with "./". requiredFiles := make(map[string]*set.StringSet) packageDeps := make(map[string]*set.StringSet) specifiedPackage := flag.Arg(1) var remainingPackages vector.StringVector remainingPackages.Push(specifiedPackage) for remainingPackages.Len() > 0 { packageName := remainingPackages.Pop() // Have we already processed this directory? _, alreadyDone := packageDeps[packageName] if alreadyDone { continue } dir := "./" + packageName dirInfo := build.GetDirectoryInfo(dir) if dirInfo.PackageName == "" { fmt.Printf("Couldn't find .go files to build in directory: %s\n", dir) os.Exit(1) } // Stash information about this package, and add its local dependencies to // the queue. requiredFiles[packageName] = dirInfo.Files packageDeps[packageName] = dirInfo.Deps // If we're testing and this is the package under test, also add its test // files and dependencies. if packageName == specifiedPackage && command == "test" { requiredFiles[packageName].Union(dirInfo.TestFiles) packageDeps[packageName].Union(dirInfo.TestDeps) } for dep := range packageDeps[packageName].Iter() { remainingPackages.Push(dep) } } // Order the packages by their dependencies. totalOrder := deps.BuildTotalOrder(packageDeps) fmt.Println("Found these packages to compile:") for _, packageName := range totalOrder { fmt.Printf(" %s\n", packageName) } // Create a directory to hold outputs, deleting the old one first. os.RemoveAll("igo-out") os.Mkdir("igo-out", 0700) // Compile each of the packages in turn. for _, currentPackage := range totalOrder { fmt.Printf("\nCompiling package: %s\n", currentPackage) compileFiles(requiredFiles[currentPackage], currentPackage) } // If this is a binary, also link it. if build.GetDirectoryInfo(specifiedPackage).PackageName == "main" { linkBinary(specifiedPackage) } // If we're testing, create a test runner, build it, and run it. if command == "test" { const outputFile = "igo-out/test_runner.go" testFuncs := build.GetDirectoryInfo(specifiedPackage).TestFuncs code := test.GenerateTestMain(specifiedPackage, testFuncs) err := ioutil.WriteFile("igo-out/test_runner.go", strings.Bytes(code), 0600) if err != nil { panic(err) } var files set.StringSet files.Insert("igo-out/test_runner.go") compileFiles(&files, "test_runner") linkBinary("test_runner") if !executeCommand("igo-out/test_runner", []string{}, "") { os.Exit(1) } } }