diff --git a/interface/grpc/core/core_test.go b/interface/grpc/core/core_test.go index 6ec7311a3..f7a2da522 100644 --- a/interface/grpc/core/core_test.go +++ b/interface/grpc/core/core_test.go @@ -1,8 +1,10 @@ package core import ( + "io" "testing" + "github.com/docker/docker/pkg/archive" "github.com/mesg-foundation/core/api" "github.com/mesg-foundation/core/container" "github.com/mesg-foundation/core/container/dockertest" @@ -11,13 +13,13 @@ import ( func newServer(t *testing.T) *Server { container, err := container.New() - require.Nil(t, err) + require.NoError(t, err) a, err := api.New(api.ContainerOption(container)) - require.Nil(t, err) + require.NoError(t, err) server, err := NewServer(APIOption(a)) - require.Nil(t, err) + require.NoError(t, err) return server } @@ -26,13 +28,21 @@ func newServerAndDockerTest(t *testing.T) (*Server, *dockertest.Testing) { dt := dockertest.New() container, err := container.New(container.ClientOption(dt.Client())) - require.Nil(t, err) + require.NoError(t, err) a, err := api.New(api.ContainerOption(container)) - require.Nil(t, err) + require.NoError(t, err) server, err := NewServer(APIOption(a)) - require.Nil(t, err) + require.NoError(t, err) return server, dt } + +func serviceTar(t *testing.T, path string) io.Reader { + reader, err := archive.TarWithOptions(path, &archive.TarOptions{ + Compression: archive.Gzip, + }) + require.NoError(t, err) + return reader +} diff --git a/interface/grpc/core/delete_test.go b/interface/grpc/core/delete_test.go index 9372e439e..e97503004 100644 --- a/interface/grpc/core/delete_test.go +++ b/interface/grpc/core/delete_test.go @@ -4,27 +4,25 @@ import ( "context" "testing" - "github.com/mesg-foundation/core/database/services" - "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -var serverdelete = new(Server) - func TestDeleteService(t *testing.T) { - emptyService := service.Service{} - - url := "https://github.com/mesg-foundation/service-webhook" + var ( + path = "./service-test-task" + server = newServer(t) + ) - server := newServer(t) - stream := newTestDeployStream(url) - server.DeployService(stream) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) - reply, err := serverdelete.DeleteService(context.Background(), &DeleteServiceRequest{ - ServiceID: stream.serviceID, + reply, err := server.DeleteService(context.Background(), &DeleteServiceRequest{ + ServiceID: s.Id, }) require.Nil(t, err) require.NotNil(t, reply) - x, _ := services.Get(stream.serviceID) - require.Equal(t, emptyService, x) + + _, err = server.api.GetService(s.Id) + require.Error(t, err) } diff --git a/interface/grpc/core/deploy_integration_test.go b/interface/grpc/core/deploy_integration_test.go index 4f0fb0ef3..db978afb3 100644 --- a/interface/grpc/core/deploy_integration_test.go +++ b/interface/grpc/core/deploy_integration_test.go @@ -8,7 +8,6 @@ import ( "github.com/cnf/structhash" "github.com/logrusorgru/aurora" - "github.com/mesg-foundation/core/database/services" "github.com/stretchr/testify/require" ) @@ -19,7 +18,8 @@ func TestIntegrationDeployService(t *testing.T) { stream := newTestDeployStream(url) require.Nil(t, server.DeployService(stream)) + defer server.api.DeleteService(stream.serviceID) + require.Equal(t, 1, structhash.Version(stream.serviceID)) require.True(t, stringSliceContains(stream.statuses, fmt.Sprintf("%s Completed.", aurora.Green("✔")))) - services.Delete(stream.serviceID) } diff --git a/interface/grpc/core/execute_test.go b/interface/grpc/core/execute_test.go index 5866bc577..dff642169 100644 --- a/interface/grpc/core/execute_test.go +++ b/interface/grpc/core/execute_test.go @@ -5,110 +5,104 @@ import ( "testing" "github.com/mesg-foundation/core/api" - "github.com/mesg-foundation/core/database/services" "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -var serverexecute = new(Server) - func TestExecute(t *testing.T) { var ( - url = "https://github.com/mesg-foundation/service-webhook" + path = "./service-test-task" taskKey = "call" data = `{"url": "https://mesg.tech", "data": {}, "headers": {}}` + server = newServer(t) ) - server := newServer(t) - stream := newTestDeployStream(url) - - server.DeployService(stream) - defer services.Delete(stream.serviceID) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - serverexecute.StartService(context.Background(), &StartServiceRequest{ - ServiceID: stream.serviceID, - }) - defer serverexecute.StopService(context.Background(), &StopServiceRequest{ - ServiceID: stream.serviceID, - }) + require.NoError(t, server.api.StartService(s.Id)) + defer server.api.StopService(s.Id) - reply, err := serverexecute.ExecuteTask(context.Background(), &ExecuteTaskRequest{ - ServiceID: stream.serviceID, + reply, err := server.ExecuteTask(context.Background(), &ExecuteTaskRequest{ + ServiceID: s.Id, TaskKey: taskKey, InputData: data, }) - require.Nil(t, err) require.NotEqual(t, "", reply.ExecutionID) } func TestExecuteWithInvalidJSON(t *testing.T) { - url := "https://github.com/mesg-foundation/service-webhook" + var ( + path = "./service-test-task" + server = newServer(t) + ) - server := newServer(t) - stream := newTestDeployStream(url) - server.DeployService(stream) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - _, err := serverexecute.ExecuteTask(context.Background(), &ExecuteTaskRequest{ - ServiceID: stream.serviceID, + _, err = server.ExecuteTask(context.Background(), &ExecuteTaskRequest{ + ServiceID: s.Id, TaskKey: "test", InputData: "", }) require.NotNil(t, err) require.Equal(t, err.Error(), "unexpected end of JSON input") - services.Delete(stream.serviceID) } func TestExecuteWithInvalidTask(t *testing.T) { - url := "https://github.com/mesg-foundation/service-webhook" - - server := newServer(t) - stream := newTestDeployStream(url) + var ( + path = "./service-test-task" + server = newServer(t) + ) - server.DeployService(stream) - defer services.Delete(stream.serviceID) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - serverexecute.StartService(context.Background(), &StartServiceRequest{ - ServiceID: stream.serviceID, - }) - defer serverexecute.StopService(context.Background(), &StopServiceRequest{ - ServiceID: stream.serviceID, - }) + require.NoError(t, server.api.StartService(s.Id)) + defer server.api.StopService(s.Id) - _, err := serverexecute.ExecuteTask(context.Background(), &ExecuteTaskRequest{ - ServiceID: stream.serviceID, + _, err = server.ExecuteTask(context.Background(), &ExecuteTaskRequest{ + ServiceID: s.Id, TaskKey: "error", InputData: "{}", }) - require.Error(t, err) require.IsType(t, (*service.TaskNotFoundError)(nil), err) } func TestExecuteWithNonRunningService(t *testing.T) { - url := "https://github.com/mesg-foundation/service-webhook" - - server := newServer(t) - stream := newTestDeployStream(url) + var ( + path = "./service-test-task" + server = newServer(t) + ) - server.DeployService(stream) - defer services.Delete(stream.serviceID) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - _, err := serverexecute.ExecuteTask(context.Background(), &ExecuteTaskRequest{ - ServiceID: stream.serviceID, + _, err = server.ExecuteTask(context.Background(), &ExecuteTaskRequest{ + ServiceID: s.Id, TaskKey: "test", InputData: "{}", }) - - require.Equal(t, &api.NotRunningServiceError{ServiceID: stream.serviceID}, err) + require.Equal(t, &api.NotRunningServiceError{ServiceID: s.Id}, err) } func TestExecuteWithNonExistingService(t *testing.T) { - _, err := serverexecute.ExecuteTask(context.Background(), &ExecuteTaskRequest{ + server := newServer(t) + + _, err := server.ExecuteTask(context.Background(), &ExecuteTaskRequest{ ServiceID: "service that doesnt exists", TaskKey: "error", InputData: "{}", }) - require.NotNil(t, err) } diff --git a/interface/grpc/core/get_service_test.go b/interface/grpc/core/get_service_test.go index 75813ecde..c2f9266bc 100644 --- a/interface/grpc/core/get_service_test.go +++ b/interface/grpc/core/get_service_test.go @@ -4,23 +4,24 @@ import ( "context" "testing" - "github.com/mesg-foundation/core/database/services" - "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -var servergetservice = new(Server) - func TestGetService(t *testing.T) { - service := &service.Service{ - Name: "TestGetService", - } - services.Save(service) - defer services.Delete(service.Id) - reply, err := servergetservice.GetService(context.Background(), &GetServiceRequest{ - ServiceID: service.Id, + var ( + path = "./service-test-task" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + reply, err := server.GetService(context.Background(), &GetServiceRequest{ + ServiceID: s.Id, }) require.Nil(t, err) require.NotNil(t, reply) - require.Equal(t, reply.Service.Name, "TestGetService") + require.Equal(t, reply.Service.Name, "Task") } diff --git a/interface/grpc/core/list_services_test.go b/interface/grpc/core/list_services_test.go index 8d7609d1f..cca4d862b 100644 --- a/interface/grpc/core/list_services_test.go +++ b/interface/grpc/core/list_services_test.go @@ -4,15 +4,17 @@ import ( "context" "testing" - "github.com/mesg-foundation/core/database/services" "github.com/stretchr/testify/require" ) -var serverlistservices = new(Server) - func TestListServices(t *testing.T) { - servicesFromAPI, err := serverlistservices.ListServices(context.Background(), &ListServicesRequest{}) - servicesFromDB, _ := services.All() - require.Nil(t, err) - require.Equal(t, len(servicesFromAPI.Services), len(servicesFromDB)) + server := newServer(t) + + reply, err := server.ListServices(context.Background(), &ListServicesRequest{}) + require.NoError(t, err) + + services, err := server.api.ListServices() + require.NoError(t, err) + + require.Equal(t, services, reply.Services) } diff --git a/interface/grpc/core/service-test-event/Dockerfile b/interface/grpc/core/service-test-event/Dockerfile new file mode 100755 index 000000000..4989c3ed3 --- /dev/null +++ b/interface/grpc/core/service-test-event/Dockerfile @@ -0,0 +1,6 @@ +FROM node:10.6.0-alpine +WORKDIR /app +COPY ./package* ./ +RUN npm install +COPY . . +CMD [ "node", "index.js" ] \ No newline at end of file diff --git a/interface/grpc/core/service-test-event/index.js b/interface/grpc/core/service-test-event/index.js new file mode 100644 index 000000000..8544ffa04 --- /dev/null +++ b/interface/grpc/core/service-test-event/index.js @@ -0,0 +1,4 @@ +const MESG = require('mesg-js').service(); +const app = require('express')(); + +app.listen(3000, () => console.log('Example app listening on port 3000!')); \ No newline at end of file diff --git a/interface/grpc/core/service-test-event/mesg.yml b/interface/grpc/core/service-test-event/mesg.yml new file mode 100644 index 000000000..0a06c9ce4 --- /dev/null +++ b/interface/grpc/core/service-test-event/mesg.yml @@ -0,0 +1,7 @@ +name: Event +description: "A service that only has events definition" +events: + request: + data: + data: + type: Object \ No newline at end of file diff --git a/interface/grpc/core/service-test-event/package.json b/interface/grpc/core/service-test-event/package.json new file mode 100644 index 000000000..3e39611a8 --- /dev/null +++ b/interface/grpc/core/service-test-event/package.json @@ -0,0 +1,12 @@ +{ + "name": "webhook", + "version": "1.0.0", + "description": "Receive HTTP connections and emit events with the data", + "main": "index.js", + "author": "Anthony Estebe ", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "mesg-js": "^1.2.1" + } +} diff --git a/interface/grpc/core/service-test-task/Dockerfile b/interface/grpc/core/service-test-task/Dockerfile new file mode 100755 index 000000000..4989c3ed3 --- /dev/null +++ b/interface/grpc/core/service-test-task/Dockerfile @@ -0,0 +1,6 @@ +FROM node:10.6.0-alpine +WORKDIR /app +COPY ./package* ./ +RUN npm install +COPY . . +CMD [ "node", "index.js" ] \ No newline at end of file diff --git a/interface/grpc/core/service-test-task/index.js b/interface/grpc/core/service-test-task/index.js new file mode 100644 index 000000000..8544ffa04 --- /dev/null +++ b/interface/grpc/core/service-test-task/index.js @@ -0,0 +1,4 @@ +const MESG = require('mesg-js').service(); +const app = require('express')(); + +app.listen(3000, () => console.log('Example app listening on port 3000!')); \ No newline at end of file diff --git a/interface/grpc/core/service-test-task/mesg.yml b/interface/grpc/core/service-test-task/mesg.yml new file mode 100644 index 000000000..feb6a7a99 --- /dev/null +++ b/interface/grpc/core/service-test-task/mesg.yml @@ -0,0 +1,14 @@ +name: Task +description: "A service that only has tasks definition" +tasks: + call: + inputs: + url: + type: String + data: + type: Object + headers: + type: Object + outputs: + result: + data: {} \ No newline at end of file diff --git a/interface/grpc/core/service-test-task/package.json b/interface/grpc/core/service-test-task/package.json new file mode 100644 index 000000000..3e39611a8 --- /dev/null +++ b/interface/grpc/core/service-test-task/package.json @@ -0,0 +1,12 @@ +{ + "name": "webhook", + "version": "1.0.0", + "description": "Receive HTTP connections and emit events with the data", + "main": "index.js", + "author": "Anthony Estebe ", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "mesg-js": "^1.2.1" + } +} diff --git a/interface/grpc/core/start_test.go b/interface/grpc/core/start_test.go index 572b26286..1a44f734a 100644 --- a/interface/grpc/core/start_test.go +++ b/interface/grpc/core/start_test.go @@ -4,28 +4,32 @@ import ( "context" "testing" - "github.com/mesg-foundation/core/database/services" "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -var serverstart = new(Server) - func TestStartService(t *testing.T) { - url := "https://github.com/mesg-foundation/service-webhook" + var ( + // we use a test service without tasks definition here otherwise we need to + // spin up the gRPC server in order to prevent service exit with failer because + // it'll try to listen for tasks. + path = "./service-test-event" + server = newServer(t) + ) - server := newServer(t) - stream := newTestDeployStream(url) - server.DeployService(stream) + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - s, _ := services.Get(stream.serviceID) - reply, err := serverstart.StartService(context.Background(), &StartServiceRequest{ - ServiceID: stream.serviceID, + _, err = server.StartService(context.Background(), &StartServiceRequest{ + ServiceID: s.Id, }) - require.Nil(t, err) - status, _ := s.Status() + require.NoError(t, err) + defer server.api.StopService(s.Id) + + s.Id = "" // TODO(ilgooz) remove this when Service type created by hand. + status, err := s.Status() + require.NoError(t, err) require.Equal(t, service.RUNNING, status) - require.NotNil(t, reply) - s.Stop() - services.Delete(stream.serviceID) } diff --git a/interface/grpc/core/stop_test.go b/interface/grpc/core/stop_test.go index b1c6c3457..7d36ecd1f 100644 --- a/interface/grpc/core/stop_test.go +++ b/interface/grpc/core/stop_test.go @@ -4,28 +4,34 @@ import ( "context" "testing" - "github.com/mesg-foundation/core/database/services" "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -var serverstop = new(Server) - func TestStopService(t *testing.T) { - url := "https://github.com/mesg-foundation/service-webhook" + var ( + // we use a test service without tasks definition here otherwise we need to + // spin up the gRPC server in order to prevent service exit with failer because + // it'll try to listen for tasks. + path = "./service-test-event" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) - server := newServer(t) - stream := newTestDeployStream(url) - server.DeployService(stream) + require.NoError(t, server.api.StartService(s.Id)) - s, _ := services.Get(stream.serviceID) - s.Start() - reply, err := serverstop.StopService(context.Background(), &StopServiceRequest{ - ServiceID: stream.serviceID, + reply, err := server.StopService(context.Background(), &StopServiceRequest{ + ServiceID: s.Id, }) - status, _ := s.Status() + + s.Id = "" // TODO(ilgooz) remove this when Service type created by hand. + status, err := s.Status() + require.NoError(t, err) require.Equal(t, service.STOPPED, status) require.Nil(t, err) require.NotNil(t, reply) - services.Delete(stream.serviceID) } diff --git a/interface/grpc/service/emit_event_test.go b/interface/grpc/service/emit_event_test.go index d3b19ab58..151da6e94 100644 --- a/interface/grpc/service/emit_event_test.go +++ b/interface/grpc/service/emit_event_test.go @@ -2,91 +2,115 @@ package service import ( "context" + "sync" "testing" - "github.com/mesg-foundation/core/database/services" - "github.com/mesg-foundation/core/pubsub" "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) func TestEmit(t *testing.T) { - server := newServer(t) - service := service.Service{ - Name: "TestEmit", - Events: map[string]*service.Event{ - "test": {}, - }, - Dependencies: map[string]*service.Dependency{ - "test": { - Image: "nginx", - }, - }, - } - services.Save(&service) - service.Id = "" // TODO(ilgooz) remove this when Service type created by hand. - defer services.Delete(service.Id) - - subscription := pubsub.Subscribe(service.EventSubscriptionChannel()) - - go server.EmitEvent(context.Background(), &EmitEventRequest{ - Token: service.Hash(), - EventKey: "test", - EventData: "{}", - }) + var ( + path = "./service-test-event" + eventKey = "request" + eventData = `{"data":{}}` + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + ln, err := server.api.ListenEvent(s.Id) + require.NoError(t, err) + defer ln.Close() - res := <-subscription - require.NotNil(t, res) + var wg sync.WaitGroup + + wg.Add(1) + go func() { + defer wg.Done() + _, err := server.EmitEvent(context.Background(), &EmitEventRequest{ + Token: s.Id, + EventKey: eventKey, + EventData: eventData, + }) + require.NoError(t, err) + }() + + event := <-ln.Events + require.Equal(t, eventKey, event.Key) + require.Equal(t, eventData, jsonMarshal(t, event.Data)) + + wg.Wait() } func TestEmitNoData(t *testing.T) { - server := newServer(t) - service := service.Service{} - services.Save(&service) - service.Id = "" // TODO(ilgooz) remove this when Service type created by hand. - defer services.Delete(service.Id) - _, err := server.EmitEvent(context.Background(), &EmitEventRequest{ - Token: service.Hash(), - EventKey: "test", + var ( + path = "./service-test-event" + eventKey = "request" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + _, err = server.EmitEvent(context.Background(), &EmitEventRequest{ + Token: s.Id, + EventKey: eventKey, }) require.Equal(t, err.Error(), "unexpected end of JSON input") } func TestEmitWrongData(t *testing.T) { - server := newServer(t) - service := service.Service{} - services.Save(&service) - service.Id = "" // TODO(ilgooz) remove this when Service type created by hand. - defer services.Delete(service.Id) - _, err := server.EmitEvent(context.Background(), &EmitEventRequest{ - Token: service.Hash(), - EventKey: "test", + var ( + path = "./service-test-event" + eventKey = "request" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + _, err = server.EmitEvent(context.Background(), &EmitEventRequest{ + Token: s.Id, + EventKey: eventKey, EventData: "", }) require.Equal(t, err.Error(), "unexpected end of JSON input") } func TestEmitWrongEvent(t *testing.T) { - server := newServer(t) - srv := service.Service{Name: "TestEmitWrongEvent"} - services.Save(&srv) - srv.Id = "" // TODO(ilgooz) remove this when Service type created by hand. - defer services.Delete(srv.Id) - _, err := server.EmitEvent(context.Background(), &EmitEventRequest{ - Token: srv.Hash(), - EventKey: "test", + var ( + path = "./service-test-event" + eventKey = "test" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + _, err = server.EmitEvent(context.Background(), &EmitEventRequest{ + Token: s.Id, + EventKey: eventKey, EventData: "{}", }) - require.NotNil(t, err) + require.Error(t, err) _, notFound := err.(*service.EventNotFoundError) require.True(t, notFound) } func TestServiceNotExists(t *testing.T) { server := newServer(t) - service := service.Service{Name: "TestServiceNotExists"} _, err := server.EmitEvent(context.Background(), &EmitEventRequest{ - Token: service.Hash(), + Token: "TestServiceNotExists", EventKey: "test", EventData: "{}", }) diff --git a/interface/grpc/service/service-test-event/Dockerfile b/interface/grpc/service/service-test-event/Dockerfile new file mode 100755 index 000000000..4989c3ed3 --- /dev/null +++ b/interface/grpc/service/service-test-event/Dockerfile @@ -0,0 +1,6 @@ +FROM node:10.6.0-alpine +WORKDIR /app +COPY ./package* ./ +RUN npm install +COPY . . +CMD [ "node", "index.js" ] \ No newline at end of file diff --git a/interface/grpc/service/service-test-event/index.js b/interface/grpc/service/service-test-event/index.js new file mode 100644 index 000000000..8544ffa04 --- /dev/null +++ b/interface/grpc/service/service-test-event/index.js @@ -0,0 +1,4 @@ +const MESG = require('mesg-js').service(); +const app = require('express')(); + +app.listen(3000, () => console.log('Example app listening on port 3000!')); \ No newline at end of file diff --git a/interface/grpc/service/service-test-event/mesg.yml b/interface/grpc/service/service-test-event/mesg.yml new file mode 100644 index 000000000..0a06c9ce4 --- /dev/null +++ b/interface/grpc/service/service-test-event/mesg.yml @@ -0,0 +1,7 @@ +name: Event +description: "A service that only has events definition" +events: + request: + data: + data: + type: Object \ No newline at end of file diff --git a/interface/grpc/service/service-test-event/package.json b/interface/grpc/service/service-test-event/package.json new file mode 100644 index 000000000..3e39611a8 --- /dev/null +++ b/interface/grpc/service/service-test-event/package.json @@ -0,0 +1,12 @@ +{ + "name": "webhook", + "version": "1.0.0", + "description": "Receive HTTP connections and emit events with the data", + "main": "index.js", + "author": "Anthony Estebe ", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "mesg-js": "^1.2.1" + } +} diff --git a/interface/grpc/service/service-test-task/Dockerfile b/interface/grpc/service/service-test-task/Dockerfile new file mode 100755 index 000000000..4989c3ed3 --- /dev/null +++ b/interface/grpc/service/service-test-task/Dockerfile @@ -0,0 +1,6 @@ +FROM node:10.6.0-alpine +WORKDIR /app +COPY ./package* ./ +RUN npm install +COPY . . +CMD [ "node", "index.js" ] \ No newline at end of file diff --git a/interface/grpc/service/service-test-task/index.js b/interface/grpc/service/service-test-task/index.js new file mode 100644 index 000000000..8544ffa04 --- /dev/null +++ b/interface/grpc/service/service-test-task/index.js @@ -0,0 +1,4 @@ +const MESG = require('mesg-js').service(); +const app = require('express')(); + +app.listen(3000, () => console.log('Example app listening on port 3000!')); \ No newline at end of file diff --git a/interface/grpc/service/service-test-task/mesg.yml b/interface/grpc/service/service-test-task/mesg.yml new file mode 100644 index 000000000..feb6a7a99 --- /dev/null +++ b/interface/grpc/service/service-test-task/mesg.yml @@ -0,0 +1,14 @@ +name: Task +description: "A service that only has tasks definition" +tasks: + call: + inputs: + url: + type: String + data: + type: Object + headers: + type: Object + outputs: + result: + data: {} \ No newline at end of file diff --git a/interface/grpc/service/service-test-task/package.json b/interface/grpc/service/service-test-task/package.json new file mode 100644 index 000000000..3e39611a8 --- /dev/null +++ b/interface/grpc/service/service-test-task/package.json @@ -0,0 +1,12 @@ +{ + "name": "webhook", + "version": "1.0.0", + "description": "Receive HTTP connections and emit events with the data", + "main": "index.js", + "author": "Anthony Estebe ", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "mesg-js": "^1.2.1" + } +} diff --git a/interface/grpc/service/service_test.go b/interface/grpc/service/service_test.go index 5f6766aa1..44629155f 100644 --- a/interface/grpc/service/service_test.go +++ b/interface/grpc/service/service_test.go @@ -1,8 +1,11 @@ package service import ( + "encoding/json" + "io" "testing" + "github.com/docker/docker/pkg/archive" "github.com/mesg-foundation/core/api" "github.com/stretchr/testify/require" ) @@ -16,3 +19,17 @@ func newServer(t *testing.T) *Server { return server } + +func serviceTar(t *testing.T, path string) io.Reader { + reader, err := archive.TarWithOptions(path, &archive.TarOptions{ + Compression: archive.Gzip, + }) + require.NoError(t, err) + return reader +} + +func jsonMarshal(t *testing.T, data interface{}) string { + bytes, err := json.Marshal(data) + require.NoError(t, err) + return string(bytes) +} diff --git a/interface/grpc/service/submit_result_test.go b/interface/grpc/service/submit_result_test.go index c96bedc04..a04a8e942 100644 --- a/interface/grpc/service/submit_result_test.go +++ b/interface/grpc/service/submit_result_test.go @@ -2,62 +2,108 @@ package service import ( "context" + "sync" "testing" "github.com/mesg-foundation/core/api" - "github.com/mesg-foundation/core/execution" - "github.com/mesg-foundation/core/service" "github.com/stretchr/testify/require" ) -func execute(name string) *execution.Execution { - var inputs map[string]interface{} - e, _ := execution.Create(&service.Service{ - Name: name, - Tasks: map[string]*service.Task{ - "test": { - Outputs: map[string]*service.Output{ - "output": {}, - }, - }, - }, - }, "test", inputs, []string{}) - e.Execute() - return e -} - func TestSubmit(t *testing.T) { - server := newServer(t) - execution := execute("TestSubmit") - reply, err := server.SubmitResult(context.Background(), &SubmitResultRequest{ - ExecutionID: execution.ID, - OutputKey: "output", - OutputData: "{}", - }) + var ( + path = "./service-test-task" + taskKey = "call" + taskData = map[string]interface{}{ + "url": "https://mesg.tech", + "data": map[string]interface{}{}, + "headers": map[string]interface{}{}, + } + outputKey = "result" + outputData = `{"data1":{}}` + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + require.NoError(t, server.api.StartService(s.Id)) + defer server.api.StopService(s.Id) + + executionID, err := server.api.ExecuteTask(s.Id, taskKey, taskData, nil) + require.NoError(t, err) + + ln, err := server.api.ListenResult(s.Id) + require.NoError(t, err) + defer ln.Close() + + var wg sync.WaitGroup + + wg.Add(1) + go func() { + defer wg.Done() + _, err := server.SubmitResult(context.Background(), &SubmitResultRequest{ + ExecutionID: executionID, + OutputKey: outputKey, + OutputData: outputData, + }) + + require.NoError(t, err) + }() - require.Nil(t, err) - require.NotNil(t, reply) + execution := <-ln.Executions + require.Equal(t, executionID, execution.ID) + require.Equal(t, outputKey, execution.Output) + require.Equal(t, outputData, jsonMarshal(t, execution.OutputData)) + + wg.Wait() } func TestSubmitWithInvalidJSON(t *testing.T) { - server := newServer(t) - execution := execute("TestSubmitWithInvalidJSON") - _, err := server.SubmitResult(context.Background(), &SubmitResultRequest{ - ExecutionID: execution.ID, - OutputKey: "output", + var ( + path = "./service-test-task" + taskKey = "call" + taskData = map[string]interface{}{ + "url": "https://mesg.tech", + "data": map[string]interface{}{}, + "headers": map[string]interface{}{}, + } + outputKey = "result" + server = newServer(t) + ) + + s, validationErr, err := server.api.DeployService(serviceTar(t, path)) + require.Zero(t, validationErr) + require.NoError(t, err) + defer server.api.DeleteService(s.Id) + + require.NoError(t, server.api.StartService(s.Id)) + defer server.api.StopService(s.Id) + + executionID, err := server.api.ExecuteTask(s.Id, taskKey, taskData, nil) + require.NoError(t, err) + + _, err = server.SubmitResult(context.Background(), &SubmitResultRequest{ + ExecutionID: executionID, + OutputKey: outputKey, OutputData: "", }) - - require.NotNil(t, err) + require.Equal(t, err.Error(), "unexpected end of JSON input") } func TestSubmitWithInvalidID(t *testing.T) { - server := newServer(t) - executionID := "xxxx" + var ( + outputKey = "output" + outputData = "{}" + executionID = "1" + server = newServer(t) + ) + _, err := server.SubmitResult(context.Background(), &SubmitResultRequest{ ExecutionID: executionID, - OutputKey: "output", - OutputData: "{}", + OutputKey: outputKey, + OutputData: outputData, }) require.Equal(t, &api.MissingExecutionError{ID: executionID}, err) }