예제 #1
0
func (m *ManifestPlugin) GetManifest(w http.ResponseWriter, r *http.Request) {
	project := mux.Vars(r)["project_id"]
	revision := mux.Vars(r)["revision"]

	version, err := version.FindOne(version.ByProjectIdAndRevision(project, revision))
	if err != nil {
		http.Error(w, fmt.Sprintf("error getting version for project %v with revision %v: %v",
			project, revision, err), http.StatusBadRequest)
		return
	}
	if version == nil {
		http.Error(w, fmt.Sprintf("version not found for project %v, with revision %v", project, revision),
			http.StatusNotFound)
		return
	}

	foundManifest, err := manifest.FindOne(manifest.ById(version.Id))
	if err != nil {
		http.Error(w, fmt.Sprintf("error getting manifest with version id %v: %v",
			version.Id, err), http.StatusBadRequest)
		return
	}
	if foundManifest == nil {
		http.Error(w, fmt.Sprintf("manifest not found for version %v", version.Id), http.StatusNotFound)
		return
	}
	plugin.WriteJSON(w, http.StatusOK, foundManifest)
	return

}
예제 #2
0
// GetPanelConfig returns a pointer to a plugin's UI configuration.
// or an error, if an error occur while trying to generate the config
// A nil pointer represents a plugin without a UI presence, and is
// not an error.
// GetPanelConfig returns a plugin.PanelConfig struct representing panels
// that will be added to the Version page.
func (m *ManifestPlugin) GetPanelConfig() (*plugin.PanelConfig, error) {
	return &plugin.PanelConfig{
		Panels: []plugin.UIPanel{
			{
				Page:      plugin.VersionPage,
				Position:  plugin.PageRight,
				PanelHTML: "<div ng-include=\"'/plugin/manifest/static/partials/version_manifest_panel.html'\"></div>",
				DataFunc: func(context plugin.UIContext) (interface{}, error) {
					if context.Version == nil {
						return nil, nil
					}
					currentManifest, err := manifest.FindOne(manifest.ById(context.Version.Id))
					if err != nil {
						return nil, err
					}
					if currentManifest == nil {
						return nil, nil
					}
					prettyManifest, err := json.MarshalIndent(currentManifest, "", "  ")
					if err != nil {
						return nil, err
					}
					return string(prettyManifest), nil
				},
			},
		},
	}, nil
}
예제 #3
0
// ManifestLoadHandler attempts to get the manifest, if it exists it updates the expansions and returns
// If it does not exist it performs GitHub API calls for each of the project's modules and gets
// the head revision of the branch and inserts it into the manifest collection.
// If there is a duplicate key error, then do a find on the manifest again.
func (mp *ManifestPlugin) ManifestLoadHandler(w http.ResponseWriter, r *http.Request) {
	task := plugin.GetTask(r)
	projectRef, err := model.FindOneProjectRef(task.Project)
	if err != nil {
		http.Error(w, fmt.Sprintf("projectRef not found for project %v: %v", task.Project, err), http.StatusNotFound)
		return
	}
	project, err := model.FindProject("", projectRef)
	if err != nil {
		http.Error(w, fmt.Sprintf("project not found for ProjectRef %v: %v", projectRef.Identifier, err),
			http.StatusNotFound)
		return
	}
	if project == nil {
		http.Error(w, fmt.Sprintf("empty project not found for ProjectRef %v: %v", projectRef.Identifier, err),
			http.StatusNotFound)
		return
	}

	// try to get the manifest
	currentManifest, err := manifest.FindOne(manifest.ById(task.Version))
	if err != nil {
		http.Error(w, fmt.Sprintf("error retrieving manifest with version id %v: %v", task.Version, err),
			http.StatusNotFound)
		return
	}
	if currentManifest != nil {
		plugin.WriteJSON(w, http.StatusOK, currentManifest)
		return
	}

	if task.Version == "" {
		http.Error(w, fmt.Sprintf("versionId is empty"), http.StatusNotFound)
		return
	}

	// attempt to insert a manifest after making GitHub API calls
	newManifest := &manifest.Manifest{
		Id:          task.Version,
		Revision:    task.Revision,
		ProjectName: task.Project,
		Branch:      project.Branch,
	}

	// populate modules
	modules := make(map[string]*manifest.Module)
	for _, module := range project.Modules {
		owner, repo := module.GetRepoOwnerAndName()
		gitBranch, err := thirdparty.GetBranchEvent(mp.OAuthCredentials, owner, repo, module.Branch)
		if err != nil {
			http.Error(w, fmt.Sprintf("error retrieving getting git branch for module %v: %v", module.Name, err),
				http.StatusNotFound)
			return
		}

		modules[module.Name] = &manifest.Module{
			Branch:   module.Branch,
			Revision: gitBranch.Commit.SHA,
			Repo:     repo,
			Owner:    owner,
			URL:      gitBranch.Commit.Url,
		}
	}
	newManifest.Modules = modules
	duplicate, err := newManifest.TryInsert()
	if err != nil {
		http.Error(w, fmt.Sprintf("error inserting manifest for %v: %v", newManifest.ProjectName, err),
			http.StatusNotFound)
		return
	}
	// if it is a duplicate, load the manifest again`
	if duplicate {
		// try to get the manifest
		m, err := manifest.FindOne(manifest.ById(task.Version))
		if err != nil {
			http.Error(w, fmt.Sprintf("error getting latest manifest for %v: %v", newManifest.ProjectName, err),
				http.StatusNotFound)
			return
		}
		if m != nil {
			plugin.WriteJSON(w, http.StatusOK, m)
			return
		}
	}
	// no duplicate key error, use the manifest just created.

	plugin.WriteJSON(w, http.StatusOK, newManifest)
	return
}
예제 #4
0
func TestTaskSuccess(t *testing.T) {
	setupTlsConfigs(t)
	testutil.ConfigureIntegrationTest(t, testConfig, "TestTaskSuccess")

	for tlsString, tlsConfig := range tlsConfigs {
		for _, testSetup := range testSetups {
			for _, variant := range buildVariantsToTest {
				Convey(testSetup.testSpec, t, func() {
					Convey("With agent running 'compile' step and live API server over "+
						tlsString+" with variant "+variant, func() {
						testTask, _, err := setupAPITestData(testConfig, "compile", variant, NoPatch, t)
						testutil.HandleTestingErr(err, t, "Couldn't create test task: %v", err)
						testServer, err := apiserver.CreateTestServer(testConfig, tlsConfig, plugin.APIPlugins, Verbose)
						testutil.HandleTestingErr(err, t, "Couldn't create apiserver: %v", err)
						testAgent, err := createAgent(testServer, testTask)
						testutil.HandleTestingErr(err, t, "failed to create agent: %v")

						// actually run the task.
						// this function won't return until the whole thing is done.
						testAgent.RunTask()
						Convey("expansions should be fetched", func() {
							So(testAgent.taskConfig.Expansions.Get("aws_key"), ShouldEqual, testConfig.Providers.AWS.Id)
							So(scanLogsForTask(testTask.Id, "fetch_expansion_value"), ShouldBeTrue)
						})
						time.Sleep(100 * time.Millisecond)
						testAgent.APILogger.FlushAndWait()
						printLogsForTask(testTask.Id)

						Convey("all scripts in task should have been run successfully", func() {
							So(scanLogsForTask(testTask.Id, "Executing script: echo \"predefined command!\""), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "executing the pre-run script"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "executing the post-run script!"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "predefined command!"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "this should not end up in the logs"), ShouldBeFalse)
							So(scanLogsForTask(testTask.Id, "Command timeout set to 21m40s"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "Command timeout set to 43m20s"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "Cloning into") || // git 1.8
								scanLogsForTask(testTask.Id, "Initialized empty Git repository"), // git 1.7
								ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "i am compiling!"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "i am sanity testing!"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "Skipping command 'git.apply_patch' on variant"), ShouldBeTrue)

							// Check that functions with args are working correctly
							So(scanLogsForTask(testTask.Id, "arg1 is FOO"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "arg2 is BAR"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "arg3 is Expanded: qux"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "arg4 is Default: default_value"), ShouldBeTrue)

							// Check that multi-command functions are working correctly
							So(scanLogsForTask(testTask.Id, "step 1 of multi-command func"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "step 2 of multi-command func"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "step 3 of multi-command func"), ShouldBeTrue)

							// Check that logging output is only flushing on a newline
							So(scanLogsForTask(testTask.Id, "this should be on the same line...as this."), ShouldBeTrue)

							testTask, err = model.FindTask(testTask.Id)
							testutil.HandleTestingErr(err, t, "Couldn't find test task: %v", err)
							So(testTask.Status, ShouldEqual, evergreen.TaskSucceeded)

							// use function display name as description when none is specified in command
							So(testTask.Details.Status, ShouldEqual, evergreen.TaskSucceeded)
							So(testTask.Details.Description, ShouldEqual, `'shell.exec' in "silent shell test"`)
							So(testTask.Details.TimedOut, ShouldBeFalse)
							So(testTask.Details.Type, ShouldEqual, model.SystemCommandType)
						})

						Convey("manifest should be created", func() {
							m, err := manifest.FindOne(manifest.ById(testTask.Version))
							So(testTask.Version, ShouldEqual, "testVersionId")
							So(err, ShouldBeNil)
							So(m, ShouldNotBeNil)
							So(m.ProjectName, ShouldEqual, testTask.Project)
							So(m.Id, ShouldEqual, testTask.Version)
							So(m.Modules, ShouldNotBeEmpty)
							So(m.Modules["recursive"], ShouldNotBeNil)
							So(m.Modules["recursive"].URL, ShouldNotEqual, "")
						})
					})

					Convey("With agent running a regular test and live API server over "+
						tlsString+" on variant "+variant, func() {
						testTask, _, err := setupAPITestData(testConfig, "normal_task", variant, NoPatch, t)
						testutil.HandleTestingErr(err, t, "Couldn't create test data: %v", err)
						testServer, err := apiserver.CreateTestServer(testConfig, tlsConfig, plugin.APIPlugins, Verbose)
						testutil.HandleTestingErr(err, t, "Couldn't create apiserver: %v", err)
						testAgent, err := createAgent(testServer, testTask)
						testutil.HandleTestingErr(err, t, "failed to create agent: %v")

						// actually run the task.
						// this function won't return until the whole thing is done.
						testAgent.RunTask()
						time.Sleep(100 * time.Millisecond)
						testAgent.APILogger.FlushAndWait()

						Convey("all scripts in task should have been run successfully", func() {
							So(scanLogsForTask(testTask.Id, "executing the pre-run script"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "executing the post-run script!"), ShouldBeTrue)

							So(scanLogsForTask(testTask.Id, "starting normal_task!"), ShouldBeTrue)
							So(scanLogsForTask(testTask.Id, "done with normal_task!"), ShouldBeTrue)

							testTask, err = model.FindTask(testTask.Id)
							testutil.HandleTestingErr(err, t, "Couldn't find test task: %v", err)
							So(testTask.Status, ShouldEqual, evergreen.TaskSucceeded)

							expectedResults := []model.TestResult{
								model.TestResult{
									Status:    "success",
									TestFile:  "t1",
									URL:       "url",
									ExitCode:  0,
									StartTime: 0,
									EndTime:   10,
								},
							}
							So(testTask.TestResults, ShouldResemble, expectedResults)
						})
					})
				})
			}
		}
	}
}
예제 #5
0
func TestManifestLoad(t *testing.T) {
	reset(t)
	testConfig := evergreen.TestConfig()

	db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig))
	testutil.ConfigureIntegrationTest(t, testConfig, "TestManifestFetch")

	Convey("With a SimpleRegistry and test project file", t, func() {

		registry := plugin.NewSimpleRegistry()
		manifestPlugin := &ManifestPlugin{}
		testutil.HandleTestingErr(registry.Register(manifestPlugin), t, "failed to register manifest plugin")

		gitPlugin := &git.GitPlugin{}
		testutil.HandleTestingErr(registry.Register(gitPlugin), t, "failed to register git plugin")

		server, err := apiserver.CreateTestServer(testConfig, nil, plugin.APIPlugins, false)
		testutil.HandleTestingErr(err, t, "Couldn't set up testing server")

		taskConfig, err := plugintest.CreateTestConfig("testdata/mongodb-mongo-master.yml", t)
		testutil.HandleTestingErr(err, t, "Couldnt get task config from config file")

		sliceAppender := &evergreen.SliceAppender{[]*slogger.Log{}}
		logger := agent.NewTestLogger(sliceAppender)

		httpCom := plugintest.TestAgentCommunicator("mocktaskid", "mocktasksecret", server.URL)

		Convey("the manifest load command should execute successfully", func() {
			for _, task := range taskConfig.Project.Tasks {
				So(len(task.Commands), ShouldNotEqual, 0)
				for _, command := range task.Commands {
					pluginCmds, err := registry.GetCommands(command, taskConfig.Project.Functions)
					testutil.HandleTestingErr(err, t, "Couldn't get plugin command: %v")
					So(pluginCmds, ShouldNotBeNil)
					So(err, ShouldBeNil)
					pluginCom := &agent.TaskJSONCommunicator{manifestPlugin.Name(),
						httpCom}
					err = pluginCmds[0].Execute(logger, pluginCom, taskConfig,
						make(chan bool))
					So(err, ShouldBeNil)
				}

			}
			Convey("the manifest should be inserted properly into the database", func() {
				currentManifest, err := manifest.FindOne(manifest.ById(taskConfig.Task.Version))
				So(err, ShouldBeNil)
				So(currentManifest, ShouldNotBeEmpty)
				So(currentManifest.ProjectName, ShouldEqual, taskConfig.ProjectRef.Identifier)
				So(currentManifest.Modules, ShouldNotBeNil)
				So(len(currentManifest.Modules), ShouldEqual, 1)
				for key, _ := range currentManifest.Modules {
					So(key, ShouldEqual, "sample")
				}
				So(taskConfig.Expansions.Get("sample_rev"), ShouldEqual, "3c7bfeb82d492dc453e7431be664539c35b5db4b")
			})
			Convey("with a manifest already in the database the manifest should not create a new manifest", func() {
				for _, task := range taskConfig.Project.Tasks {
					So(len(task.Commands), ShouldNotEqual, 0)
					for _, command := range task.Commands {
						pluginCmds, err := registry.GetCommands(command, taskConfig.Project.Functions)
						testutil.HandleTestingErr(err, t, "Couldn't get plugin command: %v")
						So(pluginCmds, ShouldNotBeNil)
						So(err, ShouldBeNil)
						pluginCom := &agent.TaskJSONCommunicator{manifestPlugin.Name(),
							httpCom}
						err = pluginCmds[0].Execute(logger, pluginCom, taskConfig,
							make(chan bool))
						So(err, ShouldBeNil)
					}

				}
				Convey("the manifest should be inserted properly into the database", func() {
					currentManifest, err := manifest.FindOne(manifest.ById(taskConfig.Task.Version))
					So(err, ShouldBeNil)
					So(currentManifest, ShouldNotBeEmpty)
					So(currentManifest.ProjectName, ShouldEqual, taskConfig.ProjectRef.Identifier)
					So(currentManifest.Modules, ShouldNotBeNil)
					So(len(currentManifest.Modules), ShouldEqual, 1)
					for key, _ := range currentManifest.Modules {
						So(key, ShouldEqual, "sample")
					}
					So(currentManifest.Modules["sample"].Repo, ShouldEqual, "sample")
					So(taskConfig.Expansions.Get("sample_rev"), ShouldEqual, "3c7bfeb82d492dc453e7431be664539c35b5db4b")
					So(currentManifest.Id, ShouldEqual, taskConfig.Task.Version)
				})
			})

		})
	})
}