Beispiel #1
0
// 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
}
Beispiel #2
0
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"))
			})

		})

	})
}
Beispiel #5
0
// 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)

		})

	})

}
Beispiel #7
0
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)

		})

	})
}