// Determines if either there is no currently built version of the agent, // or if the currently built version is out of date. // Returns whether a new version needs to be built, and an error if any // of the checks within the function throw an error. func (self *AgentBasedHostGateway) AgentNeedsBuild() (bool, error) { // compute and cache the current hash of the agent package agentHash, err := util.CurrentGitHash(self.AgentPackageDir) if err != nil { return false, fmt.Errorf("error getting git hash of agent package "+ "at %v: %v", self.AgentPackageDir, err) } self.currentAgentHash = agentHash // if the local directory where the executables live does not exist, then we // certainly need to build the agent exists, err := util.FileExists(self.ExecutablesDir) if err != nil { return false, err } if !exists { return true, nil } // if the most recently built agent hash is different from the current // mci hash, then the agent needs to be rebuilt lastBuiltRevision, err := db.GetLastAgentBuild() if err != nil { return false, fmt.Errorf("error getting last agent build hash: %v", err) } return self.currentAgentHash != lastBuiltRevision, nil }
func TestArchiveRoundTrip(t *testing.T) { Convey("After building archive with include/exclude filters", t, func() { testDir := testutil.GetDirectoryOfFile() err := os.RemoveAll(filepath.Join(testDir, "testdata", "artifacts_out.tar.gz")) testutil.HandleTestingErr(err, t, "Couldn't remove test tarball") err = os.RemoveAll(filepath.Join(testDir, "testdata", "artifacts_out")) testutil.HandleTestingErr(err, t, "Couldn't remove test tarball") f, gz, tarWriter, err := TarGzWriter(filepath.Join(testDir, "testdata", "artifacts_out.tar.gz")) testutil.HandleTestingErr(err, t, "Couldn't open test tarball") includes := []string{"dir1/**"} excludes := []string{"*.pdb"} var found int found, err = BuildArchive(tarWriter, filepath.Join(testDir, "testdata", "artifacts_in"), includes, excludes, logger) So(err, ShouldBeNil) So(found, ShouldEqual, 2) tarWriter.Close() gz.Close() f.Close() f2, gz2, tarReader, err := TarGzReader(filepath.Join(testDir, "testdata", "artifacts_out.tar.gz")) testutil.HandleTestingErr(err, t, "Couldn't open test tarball") err = Extract(tarReader, filepath.Join(testDir, "testdata", "artifacts_out")) defer f2.Close() defer gz2.Close() So(err, ShouldBeNil) exists, err := util.FileExists(filepath.Join(testDir, "testdata", "artifacts_out")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) exists, err = util.FileExists(filepath.Join(testDir, "testdata", "artifacts_out", "dir1", "dir2", "test.pdb")) So(err, ShouldBeNil) So(exists, ShouldBeFalse) // Dereference symlinks exists, err = util.FileExists(filepath.Join(testDir, "testdata", "artifacts_out", "dir1", "dir2", "my_symlink.txt")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) contents, err := ioutil.ReadFile(filepath.Join(testDir, "testdata", "artifacts_out", "dir1", "dir2", "my_symlink.txt")) So(err, ShouldBeNil) So(string(contents), ShouldEqual, "Hello, World\n") }) }
func TestTarGzCommandBuildArchive(t *testing.T) { Convey("With a targz pack command", t, func() { var cmd *TarGzPackCommand Convey("when building an archive", func() { cmd = &TarGzPackCommand{} Convey("the correct files should be included and excluded", func() { target := filepath.Join(testDataDir, "target.tgz") outputDir := filepath.Join(testDataDir, "output") testutil.HandleTestingErr(os.RemoveAll(target), t, "Error removing tgz file") testutil.HandleTestingErr(os.RemoveAll(outputDir), t, "Error removing output dir") params := map[string]interface{}{ "target": target, "source_dir": testDataDir, "include": []string{"targz_me/dir1/**"}, "exclude_files": []string{"*.pdb"}, } So(cmd.ParseParams(params), ShouldBeNil) numFound, err := cmd.BuildArchive("", &plugintest.MockLogger{}) So(err, ShouldBeNil) So(numFound, ShouldEqual, 1) exists, err := util.FileExists(target) So(err, ShouldBeNil) So(exists, ShouldBeTrue) // untar the file So(os.MkdirAll(outputDir, 0755), ShouldBeNil) untarCmd := &command.LocalCommand{ CmdString: "tar xvf ../target.tgz", WorkingDirectory: outputDir, Stdout: ioutil.Discard, Stderr: ioutil.Discard, } So(untarCmd.Run(), ShouldBeNil) // make sure that the correct files were included exists, err = util.FileExists( filepath.Join(outputDir, "targz_me/dir1/dir2/testfile.txt")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) exists, err = util.FileExists( filepath.Join(outputDir, "targz_me/dir1/dir2/test.pdb"), ) So(err, ShouldBeNil) So(exists, ShouldBeFalse) }) }) }) }
func TestScpCommand(t *testing.T) { Convey("With files to scp", t, func() { // the local files and target directory for scping evgHome := evergreen.FindEvergreenHome() tmpBase := filepath.Join(evgHome, "command/testdata/tmp") fileToScp := filepath.Join(tmpBase, "copy_me_please.txt") directoryToScp := filepath.Join(tmpBase, "copy_my_children_please") nestedFileToScp := filepath.Join(directoryToScp, "copy_me_too_please.txt") targetDirectory := filepath.Join(tmpBase, "feed_me_files") // remove the files and directories, if they exist (start clean) exists, err := util.FileExists(tmpBase) So(err, ShouldBeNil) if exists { So(os.RemoveAll(tmpBase), ShouldBeNil) } So(os.MkdirAll(tmpBase, 0777), ShouldBeNil) // prevent permissions issues syscall.Umask(0000) // create the files / directories to be used So(ioutil.WriteFile(fileToScp, []byte("hello"), 0777), ShouldBeNil) So(os.Mkdir(directoryToScp, 0777), ShouldBeNil) So(ioutil.WriteFile(nestedFileToScp, []byte("hi"), 0777), ShouldBeNil) So(os.Mkdir(targetDirectory, 0777), ShouldBeNil) Convey("when running scp commands", func() { Convey("copying files should work in both directions (local to"+ " remote and remote to local)", func() { // scp the file from local to remote scpCommand := &ScpCommand{ Source: fileToScp, Dest: targetDirectory, Stdout: ioutil.Discard, Stderr: ioutil.Discard, RemoteHostName: TestRemote, User: TestRemoteUser, Options: []string{"-i", TestRemoteKey}, SourceIsRemote: false, } So(scpCommand.Run(), ShouldBeNil) // make sure the file was scp-ed over newFileContents, err := ioutil.ReadFile( filepath.Join(targetDirectory, "copy_me_please.txt")) So(err, ShouldBeNil) So(newFileContents, ShouldResemble, []byte("hello")) // remove the file So(os.Remove(filepath.Join(targetDirectory, "copy_me_please.txt")), ShouldBeNil) // scp the file from remote to local scpCommand = &ScpCommand{ Source: fileToScp, Dest: targetDirectory, Stdout: ioutil.Discard, Stderr: ioutil.Discard, RemoteHostName: TestRemote, User: TestRemoteUser, Options: []string{"-i", TestRemoteKey}, SourceIsRemote: true, } So(scpCommand.Run(), ShouldBeNil) // make sure the file was scp-ed over newFileContents, err = ioutil.ReadFile( filepath.Join(targetDirectory, "copy_me_please.txt")) So(err, ShouldBeNil) So(newFileContents, ShouldResemble, []byte("hello")) }) Convey("additional scp options should be passed correctly to the"+ " command", func() { // scp recursively, using the -r flag scpCommand := &ScpCommand{ Source: directoryToScp, Dest: targetDirectory, Stdout: ioutil.Discard, Stderr: ioutil.Discard, RemoteHostName: TestRemote, User: TestRemoteUser, Options: []string{"-i", TestRemoteKey, "-r"}, SourceIsRemote: false, } So(scpCommand.Run(), ShouldBeNil) // make sure the entire directory was scp-ed over nestedFileContents, err := ioutil.ReadFile( filepath.Join(targetDirectory, "copy_my_children_please", "copy_me_too_please.txt")) So(err, ShouldBeNil) So(nestedFileContents, ShouldResemble, []byte("hi")) }) }) }) }
// Fetch the specified resource from s3. func (self *S3GetCommand) Get() error { // get the appropriate session and bucket auth := &aws.Auth{ AccessKey: self.AwsKey, SecretKey: self.AwsSecret, } session := thirdparty.NewS3Session(auth, aws.USEast) bucket := session.Bucket(self.Bucket) // get a reader for the bucket reader, err := bucket.GetReader(self.RemoteFile) if err != nil { return fmt.Errorf("error getting bucket reader for file %v: %v", self.RemoteFile, err) } defer reader.Close() // either untar the remote, or just write to a file if self.LocalFile != "" { // remove the file, if it exists exists, err := util.FileExists(self.LocalFile) if err != nil { return fmt.Errorf("error checking existence of local file %v: %v", self.LocalFile, err) } if exists { if err := os.RemoveAll(self.LocalFile); err != nil { return fmt.Errorf("error clearing local file %v: %v", self.LocalFile, err) } } // open the local file file, err := os.Create(self.LocalFile) if err != nil { return fmt.Errorf("error opening local file %v: %v", self.LocalFile, err) } defer file.Close() _, err = io.Copy(file, reader) return err } else { // wrap the reader in a gzip reader and a tar reader gzipReader, err := gzip.NewReader(reader) if err != nil { return fmt.Errorf("error creating gzip reader for %v: %v", self.RemoteFile, err) } tarReader := tar.NewReader(gzipReader) err = archive.Extract(tarReader, self.ExtractTo) if err != nil { return fmt.Errorf("error extracting %v to %v: %v", self.RemoteFile, self.ExtractTo, err) } } return nil }
func TestAgentBasedHostGateway(t *testing.T) { var hostGateway *AgentBasedHostGateway SkipConvey("When checking if the agent needs to be built", t, func() { hostGateway = &AgentBasedHostGateway{} Convey("a non-existent executables directory should cause the agent"+ " to need to be built", func() { hostGateway.ExecutablesDir = "/foo/bar/baz/foo/bar" needsBuild, err := hostGateway.AgentNeedsBuild() So(err, ShouldBeNil) So(needsBuild, ShouldBeTrue) }) Convey("an out-of-date last-built version of the agent should cause"+ " the agent to need to be built", func() { hostGateway.ExecutablesDir = "/" // just needs to exist // store the "last built hash" as something different than the // current one So(db.StoreLastAgentBuild("fedcba"), ShouldBeNil) needsBuild, err := hostGateway.AgentNeedsBuild() So(err, ShouldBeNil) So(needsBuild, ShouldBeTrue) }) Convey("an up-to-date last-built version of the agent should cause"+ " the agent to not need to be built", func() { hostGateway.ExecutablesDir = "/" // just needs to exist // compute and cache the current hash of the agent package agentHash, err := util.CurrentGitHash(hostGateway.AgentPackageDir) So(err, ShouldBeNil) // store the "last built hash" as the same as the current one So(db.StoreLastAgentBuild(agentHash), ShouldBeNil) needsBuild, err := hostGateway.AgentNeedsBuild() So(err, ShouldBeNil) So(needsBuild, ShouldBeFalse) }) }) SkipConvey("When building the agent", t, func() { hostGateway = &AgentBasedHostGateway{} So(db.StoreLastAgentBuild("abcdef"), ShouldBeNil) Convey("a nil AgentCompiler should cause a panic", func() { So(func() { hostGateway.buildAgent() }, ShouldPanic) }) Convey("a failed compilation should error and cause the build to not"+ " be recorded as successful", func() { // attempt to compile hostGateway.currentAgentHash = "fedcba" hostGateway.Compiler = &FailingAgentCompiler{} So(hostGateway.buildAgent(), ShouldNotBeNil) // make sure the last built hash was not updated lastBuiltHash, err := db.GetLastAgentBuild() So(err, ShouldBeNil) So(lastBuiltHash, ShouldEqual, "abcdef") }) Convey("a successful compilation should cause the build to be"+ " recorded as successful", func() { // attempt to compile hostGateway.currentAgentHash = "fedcba" hostGateway.Compiler = &SucceedingAgentCompiler{} So(hostGateway.buildAgent(), ShouldBeNil) // make sure the last built hash was updated lastBuiltHash, err := db.GetLastAgentBuild() So(err, ShouldBeNil) So(lastBuiltHash, ShouldEqual, "fedcba") }) }) Convey("When prepping the remote machine", t, func() { Convey("the remote shell should be created, and the config directory"+ " and agent binaries should be copied over to it", func() { hostGateway = &AgentBasedHostGateway{ Compiler: &SucceedingAgentCompiler{}, } // create a mock config directory, mock executables // directory, and mock remote shell evgHome := evergreen.FindEvergreenHome() tmpBase := filepath.Join(evgHome, "taskrunner/testdata/tmp") mockConfigDir := filepath.Join(tmpBase, "mock_config_dir") hostGatewayTestConf.ConfigDir = mockConfigDir mockExecutablesDir := filepath.Join(tmpBase, "mock_executables_dir") hostGateway.ExecutablesDir = mockExecutablesDir mockExecutable := filepath.Join(mockExecutablesDir, "main") mockRemoteShell := filepath.Join(tmpBase, "mock_remote_shell") evergreen.RemoteShell = mockRemoteShell // prevent permissions issues syscall.Umask(0000) // remove the directories, if they exist (start clean) exists, err := util.FileExists(tmpBase) So(err, ShouldBeNil) if exists { So(os.RemoveAll(tmpBase), ShouldBeNil) } So(os.MkdirAll(tmpBase, 0777), ShouldBeNil) // create the config and executables directories, as well as a // mock executable, to copy over So(os.Mkdir(mockConfigDir, 0777), ShouldBeNil) So(os.Mkdir(mockExecutablesDir, 0777), ShouldBeNil) So(ioutil.WriteFile(mockExecutable, []byte("run me"), 0777), ShouldBeNil) // mock up a host for localhost localhost := host.Host{ Host: command.TestRemote, User: command.TestRemoteUser, } // prep the "remote" host _, err = hostGateway.prepRemoteHost(hostGatewayTestConf, localhost, []string{"-i", command.TestRemoteKey}, "") So(err, ShouldBeNil) // make sure the correct files were created and copied over exists, err = util.FileExists(filepath.Join(mockRemoteShell, "mock_config_dir")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) exists, err = util.FileExists(filepath.Join(mockRemoteShell, "main")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) }) }) }
func TestS3PutAndGet(t *testing.T) { testutil.HandleTestingErr( db.ClearCollections(task.Collection, artifact.Collection), t, "error clearing test collections") conf := evergreen.TestConfig() testutil.ConfigureIntegrationTest(t, conf, "TestS3PutAndGet") Convey("When putting to and retrieving from an s3 bucket", t, func() { var putCmd *S3PutCommand var getCmd *S3GetCommand testDataDir := "testdata" remoteFile := "remote_mci_put_test.tgz" bucket := "mci-test-uploads" permissions := "private" contentType := "application/x-tar" displayName := "testfile" // create the local directory to be tarred localDirToTar := filepath.Join(testDataDir, "put_test") localFileToTar := filepath.Join(localDirToTar, "put_test_file.txt") testutil.HandleTestingErr(os.RemoveAll(localDirToTar), t, "Error removing"+ " directory") testutil.HandleTestingErr(os.MkdirAll(localDirToTar, 0755), t, "Error creating directory") randStr := util.RandomString() So(ioutil.WriteFile(localFileToTar, []byte(randStr), 0755), ShouldBeNil) // tar it tarCmd := &command.LocalCommand{ CmdString: "tar czf put_test.tgz put_test", WorkingDirectory: testDataDir, Stdout: ioutil.Discard, Stderr: ioutil.Discard, } testutil.HandleTestingErr(tarCmd.Run(), t, "Error tarring directories") tarballSource := filepath.Join(testDataDir, "put_test.tgz") // remove the untarred version testutil.HandleTestingErr(os.RemoveAll(localDirToTar), t, "Error removing directories") Convey("the file retrieved should be the exact same as the file put", func() { // load params into the put command putCmd = &S3PutCommand{} putParams := map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "local_file": tarballSource, "remote_file": remoteFile, "bucket": bucket, "permissions": permissions, "content_type": contentType, "display_name": displayName, } So(putCmd.ParseParams(putParams), ShouldBeNil) So(putCmd.Put(), ShouldBeNil) // next, get the file, untarring it getCmd = &S3GetCommand{} getParams := map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "remote_file": remoteFile, "bucket": bucket, "extract_to": testDataDir, "display_name": displayName, } So(getCmd.ParseParams(getParams), ShouldBeNil) So(getCmd.Get(), ShouldBeNil) // read in the file that was pulled down fileContents, err := ioutil.ReadFile(localFileToTar) So(err, ShouldBeNil) So(string(fileContents), ShouldEqual, randStr) // now, get the tarball without untarring it getCmd = &S3GetCommand{} localDlTarget := filepath.Join(testDataDir, "put_test_dl.tgz") getParams = map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "remote_file": remoteFile, "bucket": bucket, "local_file": localDlTarget, "display_name": displayName, } So(getCmd.ParseParams(getParams), ShouldBeNil) So(getCmd.Get(), ShouldBeNil) exists, err := util.FileExists(localDlTarget) So(err, ShouldBeNil) So(exists, ShouldBeTrue) }) Convey("the put command should always run if there is no variants filter", func() { // load params into the put command putCmd = &S3PutCommand{} putParams := map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "local_file": tarballSource, "remote_file": remoteFile, "bucket": bucket, "permissions": permissions, "content_type": contentType, "display_name": displayName, } So(putCmd.ParseParams(putParams), ShouldBeNil) So(putCmd.shouldRunForVariant("linux-64"), ShouldBeTrue) }) Convey("put cmd with variants filter should only run if variant is in list", func() { // load params into the put command putCmd = &S3PutCommand{} putParams := map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "local_file": tarballSource, "remote_file": remoteFile, "bucket": bucket, "permissions": permissions, "content_type": contentType, "display_name": displayName, "build_variants": []string{"linux-64", "windows-64"}, } So(putCmd.ParseParams(putParams), ShouldBeNil) So(putCmd.shouldRunForVariant("linux-64"), ShouldBeTrue) So(putCmd.shouldRunForVariant("osx-108"), ShouldBeFalse) }) Convey("put cmd with 'optional' and missing file should not throw an error", func() { // load params into the put command putCmd = &S3PutCommand{} putParams := map[string]interface{}{ "aws_key": conf.Providers.AWS.Id, "aws_secret": conf.Providers.AWS.Secret, "optional": true, "local_file": "this_file_does_not_exist.txt", "remote_file": "remote_file", "bucket": "test_bucket", "permissions": "private", "content_type": "text/plain", } So(putCmd.ParseParams(putParams), ShouldBeNil) server, err := apiserver.CreateTestServer(conf, nil, plugin.APIPlugins, false) httpCom := plugintest.TestAgentCommunicator("testTask", "taskSecret", server.URL) pluginCom := &agent.TaskJSONCommunicator{"s3", httpCom} So(err, ShouldBeNil) err = putCmd.Execute(&plugintest.MockLogger{}, pluginCom, &model.TaskConfig{nil, nil, nil, nil, &model.BuildVariant{Name: "linux"}, &command.Expansions{}, "."}, make(chan bool)) So(err, ShouldBeNil) }) }) }
func TestAgentBasedHostGateway(t *testing.T) { var hostGateway *AgentBasedHostGateway Convey("When prepping the remote machine", t, func() { Convey("the remote shell should be created, and the config directory"+ " and agent binaries should be copied over to it", func() { hostGateway = &AgentBasedHostGateway{ Compiler: &SucceedingAgentCompiler{}, } // create a mock config directory, mock executables // directory, and mock remote shell evgHome := evergreen.FindEvergreenHome() tmpBase := filepath.Join(evgHome, "taskrunner/testdata/tmp") mockConfigDir := filepath.Join(tmpBase, "mock_config_dir") hostGatewayTestConf.ConfigDir = mockConfigDir mockExecutablesDir := filepath.Join(tmpBase, "mock_executables_dir") hostGateway.ExecutablesDir = mockExecutablesDir mockExecutable := filepath.Join(mockExecutablesDir, "main") mockRemoteShell := filepath.Join(tmpBase, "mock_remote_shell") evergreen.RemoteShell = mockRemoteShell // prevent permissions issues syscall.Umask(0000) // remove the directories, if they exist (start clean) exists, err := util.FileExists(tmpBase) So(err, ShouldBeNil) if exists { So(os.RemoveAll(tmpBase), ShouldBeNil) } So(os.MkdirAll(tmpBase, 0777), ShouldBeNil) // create the config and executables directories, as well as a // mock executable, to copy over So(os.Mkdir(mockConfigDir, 0777), ShouldBeNil) So(os.Mkdir(mockExecutablesDir, 0777), ShouldBeNil) So(ioutil.WriteFile(mockExecutable, []byte("run me"), 0777), ShouldBeNil) // mock up a host for localhost localhost := host.Host{ Host: command.TestRemote, User: command.TestRemoteUser, } // prep the "remote" host _, err = hostGateway.prepRemoteHost(hostGatewayTestConf, localhost, []string{"-i", command.TestRemoteKey}, "") So(err, ShouldBeNil) // make sure the correct files were created and copied over exists, err = util.FileExists(filepath.Join(mockRemoteShell, "mock_config_dir")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) exists, err = util.FileExists(filepath.Join(mockRemoteShell, "main")) So(err, ShouldBeNil) So(exists, ShouldBeTrue) }) }) }
func TestTarGzCommandUnpackArchive(t *testing.T) { Convey("With a targz unpack command", t, func() { var cmd *TarGzUnpackCommand Convey("when unpacking an archive", func() { cmd = &TarGzUnpackCommand{} Convey("the archive's contents should be expanded into the"+ " specified target directory", func() { target := filepath.Join(testDataDir, "target.tgz") output := filepath.Join(testDataDir, "output") testutil.HandleTestingErr(os.RemoveAll(target), t, "Error removing tgz file") testutil.HandleTestingErr(os.RemoveAll(output), t, "Error removing output directory") // create the output directory testutil.HandleTestingErr(os.MkdirAll(output, 0755), t, "Error creating output directory") // use the tar gz pack command to create a tarball tarPackCmd := &TarGzPackCommand{} tarPackParams := map[string]interface{}{ "target": target, "source_dir": testDataDir, "include": []string{"targz_me/dir1/**"}, "exclude_files": []string{}, } So(tarPackCmd.ParseParams(tarPackParams), ShouldBeNil) numFound, err := tarPackCmd.BuildArchive("", &plugintest.MockLogger{}) So(err, ShouldBeNil) So(numFound, ShouldEqual, 2) // make sure it was built exists, err := util.FileExists(target) testutil.HandleTestingErr(err, t, "Error checking for file"+ " existence") So(exists, ShouldBeTrue) // now, use a tar gz unpacking command to untar the tarball tarUnpackCmd := &TarGzUnpackCommand{} tarUnpackParams := map[string]interface{}{ "source": target, "dest_dir": output, } So(tarUnpackCmd.ParseParams(tarUnpackParams), ShouldBeNil) So(tarUnpackCmd.UnpackArchive(), ShouldBeNil) // make sure the tarball was unpacked successfully exists, err = util.FileExists( filepath.Join(output, "targz_me/dir1/dir2/test.pdb")) testutil.HandleTestingErr(err, t, "Error checking file existence") So(exists, ShouldBeTrue) exists, err = util.FileExists( filepath.Join(output, "targz_me/dir1/dir2/testfile.txt")) testutil.HandleTestingErr(err, t, "Error checking file existence") So(exists, ShouldBeTrue) }) }) }) }
func TestGoxcAgentCompiler(t *testing.T) { var agentCompiler *GoxcAgentCompiler SkipConvey("When compiling the agent using goxc", t, func() { agentCompiler = &GoxcAgentCompiler{} Convey("binaries for the specified os targets and architectures"+ " should be built in the specified destination directory", func() { // create a fake go env for building evgHome := evergreen.FindEvergreenHome() mockGoPath := filepath.Join(evgHome, "src/github.com/evergreen-ci/evergreen/taskrunner/testdata/tmp/mockGoPath/") srcDir := filepath.Join(mockGoPath, "src") So(os.MkdirAll(srcDir, 0777), ShouldBeNil) binDir := filepath.Join(mockGoPath, "bin") So(os.MkdirAll(binDir, 0777), ShouldBeNil) pkgDir := filepath.Join(mockGoPath, "pkg") So(os.MkdirAll(pkgDir, 0777), ShouldBeNil) // add it to the GOPATH os.Setenv("GOPATH", os.Getenv("GOPATH")+":"+mockGoPath) // create a buildable main package inside of the source dir mainPackage := filepath.Join(srcDir, "main") So(os.MkdirAll(mainPackage, 0777), ShouldBeNil) fileContents := "package main\nimport ()\nfunc main(){}" So(ioutil.WriteFile(filepath.Join(mainPackage, "build_me.go"), []byte(fileContents), 0777), ShouldBeNil) // create the destination directory dstDir := filepath.Join(mockGoPath, "executables") // compile the source package So(agentCompiler.Compile(mainPackage, dstDir), ShouldBeNil) // make sure all of the necessary main files were created for _, execType := range []string{"darwin_386", "darwin_amd64", "linux_386", "linux_amd64", "windows_386", "windows_amd64"} { // windows binaries have .exe at the end binFile := "main" if strings.HasPrefix(execType, "windows") { binFile += ".exe" } // make sure the binary exists exists, err := util.FileExists(filepath.Join(dstDir, "snapshot", execType, binFile)) So(err, ShouldBeNil) So(exists, ShouldBeTrue) } // clean up, by removing the fake go path So(os.RemoveAll(mockGoPath), ShouldBeNil) }) }) }