HTTP API: Implement getting information about worker
authorMaciej Wereski <m.wereski@partner.samsung.com>
Tue, 10 Oct 2017 14:57:30 +0000 (16:57 +0200)
committerMaciej Wereski <m.wereski@partner.samsung.com>
Tue, 5 Jun 2018 10:48:28 +0000 (12:48 +0200)
Change-Id: Iae6bc7a4f936defc409396f43a56bd13f37a532b
Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
server/api/v1/api.go
server/api/v1/api_test.go
server/api/v1/error.go
server/api/v1/handlers.go
server/api/v1/handlers_test.go
server/api/v1/testdata/worker-info-GET.json [deleted file]
server/api/v1/testdata/worker-info-bad-uuid-GET.json [new file with mode: 0644]
server/api/v1/testdata/worker-info-missing-GET.json [new file with mode: 0644]
server/api/v1/testdata/worker-info-valid-GET.json [new file with mode: 0644]

index ca6d6f5..ae770f2 100644 (file)
@@ -24,6 +24,7 @@ import (
        "fmt"
        "net"
        "net/http"
+       "regexp"
        "strconv"
 
        . "git.tizen.org/tools/boruta"
@@ -62,6 +63,9 @@ type API struct {
        workers Workers
 }
 
+// uuidRE matches only valid UUID strings.
+var uuidRE = regexp.MustCompile("^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$")
+
 // jsonMustMarshal tries to marshal responseData to JSON. Panics if error occurs.
 // TODO(mwereski): check type of data.
 func jsonMustMarshal(data responseData) []byte {
@@ -177,3 +181,8 @@ func parseReqID(id string) (ReqID, error) {
        reqid, err := strconv.ParseUint(id, 10, 64)
        return ReqID(reqid), err
 }
+
+// isValidUUID checks if given string is properly formatted UUID.
+func isValidUUID(id string) bool {
+       return uuidRE.MatchString(id)
+}
index e624844..0883f7d 100644 (file)
@@ -41,6 +41,8 @@ const (
        dateLayout      = "2006-01-02"
        past            = "1683-09-12"
        future          = "2222-12-31"
+       validUUID       = "ec4898ac-0853-407c-8501-cbb24ef6bd77"
+       missingUUID     = "8f8ade90-a319-4275-9407-977ca3e9607c"
        validReqJSON    = `{
                "ID":1,
                "State":"WAITING",
@@ -144,6 +146,16 @@ func testFromTempl(templ *requestTest, name string, path string,
        return
 }
 
+func newWorker(uuid string, state WorkerState) WorkerInfo {
+       caps := make(Capabilities)
+       caps["UUID"] = uuid
+       return WorkerInfo{
+               WorkerUUID: WorkerUUID(uuid),
+               State:      state,
+               Caps:       caps,
+       }
+}
+
 func runTests(assert *assert.Assertions, api *API, tests []requestTest) {
        srv := httptest.NewServer(api.r)
        defer srv.Close()
@@ -315,3 +327,9 @@ func TestParseReqID(t *testing.T) {
        _, err = parseReqID(invalidID)
        assert.NotNil(err)
 }
+
+func TestIsValidUUID(t *testing.T) {
+       assert := assert.New(t)
+       assert.True(isValidUUID(validUUID))
+       assert.False(isValidUUID(invalidID))
+}
index 330523c..c6f1d76 100644 (file)
@@ -47,6 +47,8 @@ var (
        // ErrBadID is returned when User provided ID which can't be parsed into
        // uint.
        ErrBadID = errors.New("ID provided in URL isn't valid")
+       // ErrBadUUID is returned when User provided ID which isn't valid UUID.
+       ErrBadUUID = errors.New("ID provided in URL isn't valid UUID")
        // ErrIDMismatch is returned when User provided different ID values in
        // URL and JSON.
        ErrIDMismatch = errors.New("request ID set in JSON doesn't match ID from URL")
index 01a5be3..d394a56 100644 (file)
@@ -175,7 +175,18 @@ func (api *API) listWorkersHandler(r *http.Request, ps map[string]string) respon
 // getWorkerInfoHandler parses HTTP request for obtaining worker information and
 // calls GetWorkerInfo().
 func (api *API) getWorkerInfoHandler(r *http.Request, ps map[string]string) responseData {
-       return newServerError(ErrNotImplemented, "get worker info")
+       defer r.Body.Close()
+
+       if !isValidUUID(ps["id"]) {
+               return newServerError(ErrBadUUID)
+       }
+
+       workerinfo, err := api.workers.GetWorkerInfo(WorkerUUID(ps["id"]))
+       if err != nil {
+               return newServerError(err)
+       }
+
+       return workerinfo
 }
 
 // setWorkerStateHandler parses HTTP workers for setting worker state and calls
index 9ea727b..ef21485 100644 (file)
@@ -428,15 +428,34 @@ func TestGetWorkerInfoHandler(t *testing.T) {
        assert, m, api := initTest(t)
        defer m.finish()
 
+       prefix := "worker-info-"
+       path := "/api/v1/workers/"
+       methods := []string{http.MethodGet, http.MethodHead}
+       notFoundTest := testFromTempl(notFoundTestTempl, prefix, path+missingUUID, methods...)
+
+       worker := newWorker(validUUID, IDLE)
+       missingErr := NotFoundError("Worker")
+       m.wm.EXPECT().GetWorkerInfo(WorkerUUID(validUUID)).Return(worker, nil).Times(2)
+       m.wm.EXPECT().GetWorkerInfo(WorkerUUID(missingUUID)).Return(WorkerInfo{}, missingErr).Times(2)
+
        tests := []requestTest{
                {
-                       name:        "worker-info",
-                       path:        "/api/v1/workers/8",
-                       methods:     []string{http.MethodGet, http.MethodHead},
+                       name:        prefix + "valid",
+                       path:        path + validUUID,
+                       methods:     methods,
                        json:        ``,
                        contentType: contentTypeJSON,
-                       status:      http.StatusNotImplemented,
+                       status:      http.StatusOK,
                },
+               {
+                       name:        prefix + "bad-uuid",
+                       path:        path + invalidID,
+                       methods:     methods,
+                       json:        ``,
+                       contentType: contentTypeJSON,
+                       status:      http.StatusBadRequest,
+               },
+               notFoundTest,
        }
 
        runTests(assert, api, tests)
diff --git a/server/api/v1/testdata/worker-info-GET.json b/server/api/v1/testdata/worker-info-GET.json
deleted file mode 100644 (file)
index c021cc4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"error":"not implemented yet: get worker info"}
\ No newline at end of file
diff --git a/server/api/v1/testdata/worker-info-bad-uuid-GET.json b/server/api/v1/testdata/worker-info-bad-uuid-GET.json
new file mode 100644 (file)
index 0000000..4145754
--- /dev/null
@@ -0,0 +1 @@
+{"error":"invalid request: ID provided in URL isn't valid UUID"}
\ No newline at end of file
diff --git a/server/api/v1/testdata/worker-info-missing-GET.json b/server/api/v1/testdata/worker-info-missing-GET.json
new file mode 100644 (file)
index 0000000..533be90
--- /dev/null
@@ -0,0 +1 @@
+{"error":"Worker not found"}
\ No newline at end of file
diff --git a/server/api/v1/testdata/worker-info-valid-GET.json b/server/api/v1/testdata/worker-info-valid-GET.json
new file mode 100644 (file)
index 0000000..86e7c6a
--- /dev/null
@@ -0,0 +1 @@
+{"WorkerUUID":"ec4898ac-0853-407c-8501-cbb24ef6bd77","State":"IDLE","Groups":null,"Caps":{"UUID":"ec4898ac-0853-407c-8501-cbb24ef6bd77"}}
\ No newline at end of file