diff --git a/datastore/bolt/build.go b/datastore/bolt/build.go index 1a466eb86..9c0f90d82 100644 --- a/datastore/bolt/build.go +++ b/datastore/bolt/build.go @@ -1,13 +1,12 @@ package bolt import ( - "bytes" + //"bytes" "encoding/binary" - "strconv" - "time" - "github.com/boltdb/bolt" "github.com/drone/drone/common" + "strconv" + "time" ) // Build gets the specified build number for the @@ -114,6 +113,7 @@ func (db *DB) SetBuild(repo string, build *common.Build) error { }) } +/* // Status returns the status for the given repository // and build number. func (db *DB) Status(repo string, build int, status string) (*common.Status, error) { @@ -147,7 +147,7 @@ func (db *DB) StatusList(repo string, build int) ([]*common.Status, error) { }) return statuses, err } - +*/ // SetStatus inserts a new build status for the // named repository and build number. If the status already // exists an error is returned. @@ -160,7 +160,6 @@ func (db *DB) SetStatus(repo string, build int, status *common.Status) error { } // Experimental - func (db *DB) SetBuildState(repo string, build *common.Build) error { key := []byte(repo + "/" + strconv.Itoa(build.Number)) @@ -203,8 +202,14 @@ func (db *DB) SetBuildTask(repo string, build int, task *common.Task) error { if err != nil { return err } + // check index to prevent nil pointer / panic + if task.Number > len(build_.Tasks) { + return ErrKeyNotFound + } build_.Updated = time.Now().UTC().Unix() - build_.Tasks[task.Number-1] = task // TODO check index to prevent nil pointer / panic + //assuming task number is 1-based. + build_.Tasks[task.Number-1] = task return update(t, bucketBuild, key, build_) }) } + diff --git a/datastore/bolt/build_test.go b/datastore/bolt/build_test.go index 8f9d78b12..c7dcc7676 100644 --- a/datastore/bolt/build_test.go +++ b/datastore/bolt/build_test.go @@ -1,11 +1,10 @@ package bolt import ( - "os" - "testing" - "github.com/drone/drone/common" . "github.com/franela/goblin" + "os" + "testing" ) func TestBuild(t *testing.T) { @@ -13,6 +12,11 @@ func TestBuild(t *testing.T) { g.Describe("Build", func() { var db *DB // temporary database repo := string("github.com/octopod/hq") + //testUser := &common.User{Login: "octocat"} + //testRepo := &common.Repo{FullName: "github.com/octopod/hq"} + testUser := "octocat" + testRepo := "github.com/octopod/hq" + //testBuild := 1 // create a new database before each unit // test and destroy afterwards. @@ -62,5 +66,67 @@ func TestBuild(t *testing.T) { g.Assert(err).Equal(nil) g.Assert(len(builds)).Equal(3) }) + + g.It("Should set build status: SetBuildStatus()", func() { + //err := db.SetRepoNotExists(testUser, testRepo) + err := db.SetRepoNotExists(&common.User{Login: testUser}, &common.Repo{FullName: testRepo}) + g.Assert(err).Equal(nil) + + db.SetBuild(repo, &common.Build{State: "error"}) + db.SetBuild(repo, &common.Build{State: "pending"}) + db.SetBuild(repo, &common.Build{State: "success"}) + err_ := db.SetBuildStatus(repo, 1, &common.Status{Context: "pending"}) + g.Assert(err_).Equal(nil) + err_ = db.SetBuildStatus(repo, 2, &common.Status{Context: "running"}) + g.Assert(err_).Equal(nil) + err_ = db.SetBuildStatus(repo, 3, &common.Status{Context: "success"}) + g.Assert(err_).Equal(nil) + }) + + g.It("Should set build state: SetBuildState()", func() { + err := db.SetRepoNotExists(&common.User{Login: testUser}, &common.Repo{FullName: testRepo}) + g.Assert(err).Equal(nil) + + db.SetBuild(repo, &common.Build{State: "error"}) + db.SetBuild(repo, &common.Build{State: "pending"}) + db.SetBuild(repo, &common.Build{State: "success"}) + err_ := db.SetBuildState(repo, &common.Build{Number: 1}) + g.Assert(err_).Equal(nil) + err_ = db.SetBuildState(repo, &common.Build{Number: 2}) + g.Assert(err_).Equal(nil) + err_ = db.SetBuildState(repo, &common.Build{Number: 3}) + g.Assert(err_).Equal(nil) + }) + + g.It("Should set build task: SetBuildTask()", func() { + err_ := db.SetRepoNotExists(&common.User{Login: testUser}, &common.Repo{FullName: testRepo}) + g.Assert(err_).Equal(nil) + // setting up tasks. + tasks := []*common.Task{ + &common.Task{ + Number: 1, + State: "pending", + ExitCode: 0, + }, + &common.Task{ + Number: 2, + State: "running", + ExitCode: 0, + }, + &common.Task{ + Number: 3, + State: "success", + ExitCode: 0, + }, + } + // setting up builds. + err_ = db.SetBuild(repo, &common.Build{Number: 1, State: "failed", Tasks: tasks}) + g.Assert(err_).Equal(nil) + err_ = db.SetBuildTask(repo, 1, &common.Task{Number: 1, State: "error", ExitCode: -1}) + g.Assert(err_).Equal(nil) + db.SetBuild(repo, &common.Build{Number: 2, State: "success", Tasks: tasks}) + err_ = db.SetBuildTask(repo, 2, &common.Task{Number: 1, State: "success", ExitCode: 0}) + g.Assert(err_).Equal(nil) + }) }) } diff --git a/datastore/bolt/repo_test.go b/datastore/bolt/repo_test.go index 397f1d4bf..a8797058a 100644 --- a/datastore/bolt/repo_test.go +++ b/datastore/bolt/repo_test.go @@ -1,12 +1,11 @@ package bolt import ( + "github.com/drone/drone/common" + . "github.com/franela/goblin" "io/ioutil" "os" "testing" - - "github.com/drone/drone/common" - . "github.com/franela/goblin" ) func TestRepo(t *testing.T) { @@ -162,3 +161,55 @@ func TestRepo(t *testing.T) { }) } + +func TestRepoDel(t *testing.T) { + g := Goblin(t) + g.Describe("Delete repo", func() { + + var db *DB // temporary database + + user := &common.User{Login: "freya"} + repoUri := string("github.com/octopod/hq") + + // create a new database before each unit + // test and destroy afterwards. + g.BeforeEach(func() { + file, err := ioutil.TempFile(os.TempDir(), "drone-bolt") + if err != nil { + panic(err) + } + + db = Must(file.Name()) + }) + g.AfterEach(func() { + os.Remove(db.Path()) + }) + + g.It("should cleanup", func() { + repo := &common.Repo{FullName: repoUri} + err := db.SetRepoNotExists(user, repo) + g.Assert(err).Equal(nil) + + db.SetBuild(repoUri, &common.Build{State: "success"}) + db.SetBuild(repoUri, &common.Build{State: "success"}) + db.SetBuild(repoUri, &common.Build{State: "pending"}) + + db.SetBuildStatus(repoUri, 1, &common.Status{Context: "success"}) + db.SetBuildStatus(repoUri, 2, &common.Status{Context: "success"}) + db.SetBuildStatus(repoUri, 3, &common.Status{Context: "pending"}) + + // first a little sanity to validate our test conditions + _, err = db.BuildLast(repoUri) + g.Assert(err).Equal(nil) + + // now run our specific test suite + // 1. ensure that we can delete the repo + err = db.DelRepo(repo) + g.Assert(err).Equal(nil) + + // 2. ensure that deleting the repo cleans up other references + _, err = db.Build(repoUri, 1) + g.Assert(err).Equal(ErrKeyNotFound) + }) + }) +} diff --git a/datastore/bolt/task.go b/datastore/bolt/task.go index ff09fcf13..ae23a8c39 100644 --- a/datastore/bolt/task.go +++ b/datastore/bolt/task.go @@ -3,73 +3,10 @@ package bolt import ( "bytes" "github.com/boltdb/bolt" - //"github.com/drone/drone/common" "io" "strconv" ) -/* - Brad Rydzewski1:00 PM - the `Task`, `TaskList` and `SetTask` are deprecated and can be probably be removed. - I just need to make sure we aren't still using those functions anywhere else in the code -*/ -/* -// GetTask gets the task at index N for the named -// repository and build number. -func (db *DB) Task(repo string, build int, task int) (*common.Task, error) { - key := []byte(repo + "/" + strconv.Itoa(build) + "/" + strconv.Itoa(task)) - task_ := &common.Task{} - err := db.View(func(t *bolt.Tx) error { - return get(t, bucketBuildTasks, key, task_) - }) - return task_, err -} - -// TaskList gets all tasks for the named repository -// and build number. -func (db *DB) TaskList(repo string, build int) ([]*common.Task, error) { - // fetch the build so that we can get the - // number of child tasks. - build_, err := db.Build(repo, build) - if err != nil { - return nil, err - } - - t, err := db.Begin(false) - if err != nil { - return nil, err - } - defer t.Rollback() - - // based on the number of child tasks, incrment - // and loop to get each task from the bucket. - tasks := []*common.Task{} - for i := 1; i <= build_.Number; i++ { - key := []byte(repo + "/" + strconv.Itoa(build) + "/" + strconv.Itoa(i)) - raw := t.Bucket(bucketBuildTasks).Get(key) - if raw == nil { - return nil, ErrKeyNotFound - } - task := &common.Task{} - err := decode(raw, task) - if err != nil { - return nil, err - } - tasks = append(tasks, task) - } - return tasks, nil -} - -// SetTask inserts or updates a task for the named -// repository and build number. -func (db *DB) SetTask(repo string, build int, task *common.Task) error { - key := []byte(repo + "/" + strconv.Itoa(build) + "/" + strconv.Itoa(task.Number)) - return db.Update(func(t *bolt.Tx) error { - return update(t, bucketBuildTasks, key, task) - }) -} -*/ - // SetLogs inserts or updates a task logs for the // named repository and build number. func (db *DB) SetLogs(repo string, build int, task int, log []byte) error { diff --git a/datastore/bolt/task_test.go b/datastore/bolt/task_test.go index 573c75570..87d8905e3 100644 --- a/datastore/bolt/task_test.go +++ b/datastore/bolt/task_test.go @@ -28,43 +28,6 @@ func TestTask(t *testing.T) { os.Remove(db.Path()) }) - /* - Brad Rydzewski1:00 PM - the `Task`, `TaskList` and `SetTask` are deprecated and can be probably be removed. - I just need to make sure we aren't still using those functions anywhere else in the code - */ - /* - g.It("Should get TaskList", func() { - db.SetRepo(&common.Repo{FullName: testRepo}) - //db.SetRepoNotExists(&common.User{Login: testUser}, &common.Repo{FullName: testRepo}) - err := db.SetTask(testRepo, testBuild, &common.Task{Number: testTask}) - g.Assert(err).Equal(nil) - err_ := db.SetTask(testRepo, testBuild, &common.Task{Number: testTask2}) - g.Assert(err_).Equal(nil) - // - tasks, err := db.TaskList(testRepo, testBuild) - // We seem to have an issue here. TaskList doesn't seem to be returning - // All the tasks added to to repo/build. So commenting these for now. - //g.Assert(err).Equal(nil) - //g.Assert(len(tasks)).Equal(2) - }) - - g.It("Should set Task", func() { - db.SetRepo(&common.Repo{FullName: testRepo}) - err := db.SetTask(testRepo, testBuild, &common.Task{Number: testTask}) - g.Assert(err).Equal(nil) - }) - - g.It("Should get Task", func() { - db.SetRepo(&common.Repo{FullName: testRepo}) - db.SetTask(testRepo, testBuild, &common.Task{Number: testTask}) - // - task, err := db.Task(testRepo, testBuild, testTask) - g.Assert(err).Equal(nil) - g.Assert(task.Number).Equal(testTask) - }) - */ - g.It("Should set Logs", func() { db.SetRepo(&common.Repo{FullName: testRepo}) //db.SetTask(testRepo, testBuild, &common.Task{Number: testTask}) diff --git a/datastore/datastore.go b/datastore/datastore.go index 01dc738e8..359884d5d 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -116,29 +116,17 @@ type Datastore interface { // Status returns the status for the given repository // and build number. - Status(string, int, string) (*common.Status, error) + ////Status(string, int, string) (*common.Status, error) // StatusList returned a list of all build statues for // the given repository and build number. - StatusList(string, int) ([]*common.Status, error) + ////StatusList(string, int) ([]*common.Status, error) // SetStatus inserts a new build status for the // named repository and build number. If the status already // exists an error is returned. SetStatus(string, int, *common.Status) error - // GetTask gets the task at index N for the named - // repository and build number. - //Task(string, int, int) (*common.Task, error) - - // TaskList gets all tasks for the named repository - // and build number. - //TaskList(string, int) ([]*common.Task, error) - - // SetTask inserts or updates a task for the named - // repository and build number. - //SetTask(string, int, *common.Task) error - // LogReader gets the task logs at index N for // the named repository and build number. LogReader(string, int, int) (io.Reader, error) diff --git a/server/builds.go b/server/builds.go index ac84bdb80..ddb231a28 100644 --- a/server/builds.go +++ b/server/builds.go @@ -90,7 +90,7 @@ func PostBuildStatus(c *gin.Context) { c.AbortWithStatus(400) return } - if err := store.SetStatus(repo.Name, num, in); err != nil { + if err := store.SetBuildStatus(repo.Name, num, in); err != nil { c.Fail(400, err) } else { c.JSON(201, in)