github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/validator/patch_test.go (about)

     1  package validator
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/evergreen-ci/evergreen/db"
    10  	"github.com/evergreen-ci/evergreen/model"
    11  	"github.com/evergreen-ci/evergreen/model/build"
    12  	"github.com/evergreen-ci/evergreen/model/distro"
    13  	"github.com/evergreen-ci/evergreen/model/patch"
    14  	"github.com/evergreen-ci/evergreen/model/task"
    15  	modelutil "github.com/evergreen-ci/evergreen/model/testutil"
    16  	"github.com/evergreen-ci/evergreen/model/version"
    17  	"github.com/evergreen-ci/evergreen/testutil"
    18  	. "github.com/smartystreets/goconvey/convey"
    19  	"gopkg.in/yaml.v2"
    20  )
    21  
    22  var (
    23  	patchTestConfig = testutil.TestConfig()
    24  	configFilePath  = "testing/mci.yml"
    25  	patchedProject  = "mci-config"
    26  	patchedRevision = "582257a4ca3a9c890959b04d4dd2de5e4d34e9e7"
    27  	patchFile       = "testdata/patch.diff"
    28  	patchOwner      = "deafgoat"
    29  	patchRepo       = "config"
    30  	patchBranch     = "master"
    31  
    32  	// newProjectPatchFile is a diff that adds a new project configuration file
    33  	// located at newConfigFilePath.
    34  	newProjectPatchFile = "testdata/project.diff"
    35  	newConfigFilePath   = "testing/project2.config"
    36  )
    37  
    38  func init() {
    39  	db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(patchTestConfig))
    40  
    41  	current := testutil.GetDirectoryOfFile()
    42  	patchFile = filepath.Join(current, patchFile)
    43  	newProjectPatchFile = filepath.Join(current, newProjectPatchFile)
    44  }
    45  
    46  func clearAll(t *testing.T) {
    47  	testutil.HandleTestingErr(
    48  		db.ClearCollections(
    49  			model.ProjectRefCollection,
    50  			patch.Collection,
    51  			version.Collection,
    52  			build.Collection,
    53  			task.Collection,
    54  			distro.Collection,
    55  		), t, "Error clearing test collection: %v")
    56  }
    57  
    58  // resetPatchSetup clears the ProjectRef, Patch, Version, Build, and Task Collections
    59  // and creates a patch from the test path given.
    60  func resetPatchSetup(t *testing.T, testPath string) *patch.Patch {
    61  	clearAll(t)
    62  	projectRef := &model.ProjectRef{
    63  		Identifier: patchedProject,
    64  		RemotePath: configFilePath,
    65  		Owner:      patchOwner,
    66  		Repo:       patchRepo,
    67  		Branch:     patchBranch,
    68  	}
    69  	// insert distros to be used
    70  	distros := []distro.Distro{{Id: "d1"}, {Id: "d2"}}
    71  	for _, d := range distros {
    72  		err := d.Insert()
    73  		testutil.HandleTestingErr(err, t, "Couldn't insert test distro: %v", err)
    74  	}
    75  
    76  	err := projectRef.Insert()
    77  	testutil.HandleTestingErr(err, t, "Couldn't insert test project ref: %v", err)
    78  
    79  	fileBytes, err := ioutil.ReadFile(patchFile)
    80  	testutil.HandleTestingErr(err, t, "Couldn't read patch file: %v", err)
    81  
    82  	// this patch adds a new task to the existing build
    83  	configPatch := &patch.Patch{
    84  		Id:            "52549c143122",
    85  		Project:       patchedProject,
    86  		Githash:       patchedRevision,
    87  		Tasks:         []string{"taskTwo", "taskOne"},
    88  		BuildVariants: []string{"linux-64-duroff"},
    89  		Patches: []patch.ModulePatch{
    90  			{
    91  				Githash: "revision",
    92  				PatchSet: patch.PatchSet{
    93  					Patch: fmt.Sprintf(string(fileBytes), testPath, testPath, testPath, testPath),
    94  					Summary: []patch.Summary{
    95  						{Name: configFilePath, Additions: 4, Deletions: 80},
    96  						{Name: "random.txt", Additions: 6, Deletions: 0},
    97  					},
    98  				},
    99  			},
   100  		},
   101  	}
   102  	err = configPatch.Insert()
   103  	testutil.HandleTestingErr(err, t, "Couldn't insert test patch: %v", err)
   104  	return configPatch
   105  }
   106  
   107  func resetProjectlessPatchSetup(t *testing.T) *patch.Patch {
   108  	clearAll(t)
   109  	projectRef := &model.ProjectRef{
   110  		Identifier: patchedProject,
   111  		RemotePath: newConfigFilePath,
   112  		Owner:      patchOwner,
   113  		Repo:       patchRepo,
   114  		Branch:     patchBranch,
   115  	}
   116  	// insert distros to be used
   117  	distros := []distro.Distro{{Id: "d1"}, {Id: "d2"}}
   118  	for _, d := range distros {
   119  		err := d.Insert()
   120  		testutil.HandleTestingErr(err, t, "Couldn't insert test distro: %v", err)
   121  	}
   122  
   123  	err := projectRef.Insert()
   124  	testutil.HandleTestingErr(err, t, "Couldn't insert test project ref: %v", err)
   125  
   126  	fileBytes, err := ioutil.ReadFile(newProjectPatchFile)
   127  	testutil.HandleTestingErr(err, t, "Couldn't read patch file: %v", err)
   128  
   129  	// this patch adds a new task to the existing build
   130  	configPatch := &patch.Patch{
   131  		Id:            "52549c143123",
   132  		Project:       patchedProject,
   133  		BuildVariants: []string{"linux-64-duroff"},
   134  		Githash:       patchedRevision,
   135  		Patches: []patch.ModulePatch{
   136  			{
   137  				Githash: "revision",
   138  				PatchSet: patch.PatchSet{
   139  					Patch:   string(fileBytes),
   140  					Summary: []patch.Summary{{Name: newConfigFilePath}},
   141  				},
   142  			},
   143  		},
   144  	}
   145  	err = configPatch.Insert()
   146  	testutil.HandleTestingErr(err, t, "Couldn't insert test patch: %v", err)
   147  	return configPatch
   148  }
   149  
   150  func TestProjectRef(t *testing.T) {
   151  	Convey("When inserting a project ref", t, func() {
   152  		err := modelutil.CreateTestLocalConfig(patchTestConfig, "mci-test", "")
   153  		So(err, ShouldBeNil)
   154  		projectRef, err := model.FindOneProjectRef("mci-test")
   155  		So(err, ShouldBeNil)
   156  		So(projectRef, ShouldNotBeNil)
   157  		So(projectRef.Identifier, ShouldEqual, "mci-test")
   158  	})
   159  }
   160  
   161  func TestGetPatchedProject(t *testing.T) {
   162  	testutil.ConfigureIntegrationTest(t, patchTestConfig, "TestConfigurePatch")
   163  	Convey("With calling GetPatchedProject with a config and remote configuration path",
   164  		t, func() {
   165  			Convey("Calling GetPatchedProject returns a valid project given a patch and settings", func() {
   166  				configPatch := resetPatchSetup(t, configFilePath)
   167  				project, err := GetPatchedProject(configPatch, patchTestConfig)
   168  				So(err, ShouldBeNil)
   169  				So(project, ShouldNotBeNil)
   170  			})
   171  
   172  			Convey("Calling GetPatchedProject on a project-less version returns a valid project", func() {
   173  				configPatch := resetProjectlessPatchSetup(t)
   174  				project, err := GetPatchedProject(configPatch, patchTestConfig)
   175  				So(err, ShouldBeNil)
   176  				So(project, ShouldNotBeNil)
   177  			})
   178  
   179  			Reset(func() {
   180  				So(db.Clear(distro.Collection), ShouldBeNil)
   181  			})
   182  		})
   183  }
   184  
   185  func TestFinalizePatch(t *testing.T) {
   186  	testutil.ConfigureIntegrationTest(t, patchTestConfig, "TestFinalizePatch")
   187  
   188  	Convey("With FinalizePatch on a project and commit event generated from GetPatchedProject path",
   189  		t, func() {
   190  			configPatch := resetPatchSetup(t, configFilePath)
   191  			Convey("a patched config should drive version creation", func() {
   192  				project, err := GetPatchedProject(configPatch, patchTestConfig)
   193  				So(err, ShouldBeNil)
   194  				yamlBytes, err := yaml.Marshal(project)
   195  				So(err, ShouldBeNil)
   196  				configPatch.PatchedConfig = string(yamlBytes)
   197  				version, err := model.FinalizePatch(configPatch, patchTestConfig)
   198  				So(err, ShouldBeNil)
   199  				So(version, ShouldNotBeNil)
   200  				// ensure the relevant builds/tasks were created
   201  				builds, err := build.Find(build.All)
   202  				So(err, ShouldBeNil)
   203  				So(len(builds), ShouldEqual, 1)
   204  				So(len(builds[0].Tasks), ShouldEqual, 2)
   205  				tasks, err := task.Find(task.All)
   206  				So(err, ShouldBeNil)
   207  				So(len(tasks), ShouldEqual, 2)
   208  			})
   209  
   210  			Convey("a patch that does not include the remote config should not "+
   211  				"drive version creation", func() {
   212  				patchedConfigFile := "fakeInPatchSoNotPatched"
   213  				configPatch := resetPatchSetup(t, patchedConfigFile)
   214  				project, err := GetPatchedProject(configPatch, patchTestConfig)
   215  				So(err, ShouldBeNil)
   216  				yamlBytes, err := yaml.Marshal(project)
   217  				So(err, ShouldBeNil)
   218  				configPatch.PatchedConfig = string(yamlBytes)
   219  				version, err := model.FinalizePatch(configPatch, patchTestConfig)
   220  				So(err, ShouldBeNil)
   221  				So(version, ShouldNotBeNil)
   222  				So(err, ShouldBeNil)
   223  				So(version, ShouldNotBeNil)
   224  
   225  				// ensure the relevant builds/tasks were created
   226  				builds, err := build.Find(build.All)
   227  				So(err, ShouldBeNil)
   228  				So(len(builds), ShouldEqual, 1)
   229  				So(len(builds[0].Tasks), ShouldEqual, 1)
   230  				tasks, err := task.Find(task.All)
   231  				So(err, ShouldBeNil)
   232  				So(len(tasks), ShouldEqual, 1)
   233  			})
   234  
   235  			Reset(func() {
   236  				So(db.Clear(distro.Collection), ShouldBeNil)
   237  			})
   238  		})
   239  }