diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index ad498fa..d8038d2 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -9,8 +9,8 @@ start: build-all rabbit-start calendar-start scheduler-start sender-start stop: scheduler-stop sender-stop calendar-stop rabbit-stop -integration: - go test -v -race ./cmd/calendar/... +integration-test: + go test -count 10 -race ./cmd/calendar/... --config ./../../configs/calendar.conf test: go test -race ./internal/... ./pkg/... diff --git a/hw12_13_14_15_calendar/cmd/calendar/main_test.go b/hw12_13_14_15_calendar/cmd/calendar/main_test.go index 50dfc20..9828b81 100644 --- a/hw12_13_14_15_calendar/cmd/calendar/main_test.go +++ b/hw12_13_14_15_calendar/cmd/calendar/main_test.go @@ -4,6 +4,7 @@ import ( "context" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/duration" + "github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/timestamp" "github.com/stretchr/testify/require" "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public" @@ -11,6 +12,7 @@ import ( "sync" "testing" "time" + "os" ) var _ = func() bool { @@ -37,24 +39,34 @@ var testEvent02 = public.CreateReq{ NotifyTime: dur2pbduration(5 * time.Minute), UserID: 2222, } - -func TestSimple(t *testing.T) { - wg := sync.WaitGroup{} +func TestMain(m *testing.M) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() go func(ctx context.Context) { main() }(ctx) - publicAPI, err := public.NewClient("localhost", "50051") + time.Sleep(1*time.Second) + + c := m.Run() + + cancel() + os.Exit(c) +} + +func TestPublicGRPCEndpoint(t *testing.T) { + wg := sync.WaitGroup{} + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + publicAPI, err := public.NewClient(ctx, "localhost", "50051") require.NoError(t, err) - wg.Add(2) + wg.Add(5) // Реализовать тесты логики приложения: - t.Run("test public GRPC.Create with GRPC.GetById", func(t *testing.T) { + t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) { defer wg.Done() resp1, err := publicAPI.Create(ctx, &testEvent01) require.NoError(t, err) require.Greater(t, resp1.ID, int64(0)) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) require.NoError(t, err) require.Equal(t, 1, len(resp2.Events)) @@ -64,7 +76,7 @@ func TestSimple(t *testing.T) { require.Equal(t, testEvent01.Note, resp2.Events[0].Note) }) - t.Run("test public GRPC.Update with GRPC.GetById", func(t *testing.T) { + t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) { defer wg.Done() resp1, err := publicAPI.Create(ctx, &testEvent01) require.NoError(t, err) @@ -79,9 +91,158 @@ func TestSimple(t *testing.T) { require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds) require.Equal(t, testEvent02.Note, resp2.Events[0].Note) }) + + t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.Error(t, err) + require.Nil(t, resp2) + }) + + t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + resp2, err := publicAPI.Create(ctx, &testEvent02) + require.NoError(t, err) + require.NotEqual(t, resp1.ID, resp2.ID) + + list, err := publicAPI.List(ctx, &empty.Empty{}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1, e2 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + if v.ID==resp2.ID { + e2=true + } + } + require.True(t, e1) + require.True(t, e2) + }) + + t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T){ + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + list, err := publicAPI.GetByDate(ctx,&public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + } + require.True(t, e1) + }) + wg.Wait() } +func TestPublicAPIEndpoint(t *testing.T) { + wg := sync.WaitGroup{} + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + publicAPI, err := public.NewClient(ctx, "localhost", "50051") + require.NoError(t, err) + + wg.Add(5) + // Реализовать тесты логики приложения: + t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent01.Title, resp2.Events[0].Title) + require.Equal(t, testEvent01.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent01.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent01.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Update(ctx, &public.UpdateReq{ID: resp1.ID, Event: &public.Event{ID: resp1.ID, Title: testEvent02.Title, Date: testEvent02.Date, Latency: testEvent02.Latency, Note: testEvent02.Note, UserID: testEvent02.UserID, NotifyTime: testEvent02.NotifyTime}}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent02.Title, resp2.Events[0].Title) + require.Equal(t, testEvent02.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent02.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.Error(t, err) + require.Nil(t, resp2) + }) + + t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + resp2, err := publicAPI.Create(ctx, &testEvent02) + require.NoError(t, err) + require.NotEqual(t, resp1.ID, resp2.ID) + + list, err := publicAPI.List(ctx, &empty.Empty{}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1, e2 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + if v.ID==resp2.ID { + e2=true + } + } + require.True(t, e1) + require.True(t, e2) + }) + + t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T){ + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + list, err := publicAPI.GetByDate(ctx,&public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + } + require.True(t, e1) + }) + + wg.Wait() +} + + func time2pbtimestamp(t time.Time) *timestamp.Timestamp { r, err := ptypes.TimestampProto(t) if err != nil { diff --git a/hw12_13_14_15_calendar/cmd/integration/calendar.go b/hw12_13_14_15_calendar/cmd/integration/calendar.go new file mode 100644 index 0000000..5be34ea --- /dev/null +++ b/hw12_13_14_15_calendar/cmd/integration/calendar.go @@ -0,0 +1,250 @@ +package main + +import ( + "context" + "fmt" + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/duration" + "github.com/golang/protobuf/ptypes/empty" + "github.com/golang/protobuf/ptypes/timestamp" + "github.com/stretchr/testify/require" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public" + "log" + "sync" + "testing" + "time" +) + +var testEvent01 = public.CreateReq{ + Title: "Test event 01", + Date: time2pbtimestamp(time.Now().Add(30 * time.Second)), + Latency: dur2pbduration(24 * time.Hour), + Note: "Note of test event 01", + NotifyTime: dur2pbduration(5 * time.Minute), + UserID: 1111, +} + +var testEvent02 = public.CreateReq{ + Title: "Test event 02", + Date: time2pbtimestamp(time.Now().Add(60 * time.Second)), + Latency: dur2pbduration(2 * 24 * time.Hour), + Note: "Note of test event 02", + NotifyTime: dur2pbduration(5 * time.Minute), + UserID: 2222, +} + +func main() { + if err := TestPublicAPIEndpoint(); err != nil { + log.Fatalf("TestPublicAPIEndpoint FAIL: %w",err) + } + + if err := TestPublicGRPCEndpoint(); err != nil { + log.Fatalf("TestPublicGRPCEndpoint FAIL: %w",err) + } + +} + +func TestPublicGRPCEndpoint() error { + wg := sync.WaitGroup{} + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + publicAPI, err := public.NewClient(ctx, "localhost", "50051") + if err != nil { + return err + } + + wg.Add(5) + // Реализовать тесты логики приложения: + t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent01.Title, resp2.Events[0].Title) + require.Equal(t, testEvent01.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent01.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent01.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Update(ctx, &public.UpdateReq{ID: resp1.ID, Event: &public.Event{ID: resp1.ID, Title: testEvent02.Title, Date: testEvent02.Date, Latency: testEvent02.Latency, Note: testEvent02.Note, UserID: testEvent02.UserID, NotifyTime: testEvent02.NotifyTime}}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent02.Title, resp2.Events[0].Title) + require.Equal(t, testEvent02.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent02.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.Error(t, err) + require.Nil(t, resp2) + }) + + t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + resp2, err := publicAPI.Create(ctx, &testEvent02) + require.NoError(t, err) + require.NotEqual(t, resp1.ID, resp2.ID) + + list, err := publicAPI.List(ctx, &empty.Empty{}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1, e2 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + if v.ID==resp2.ID { + e2=true + } + } + require.True(t, e1) + require.True(t, e2) + }) + + t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T){ + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + list, err := publicAPI.GetByDate(ctx,&public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + } + require.True(t, e1) + }) + + wg.Wait() +} + +func TestPublicAPIEndpoint() error { + wg := sync.WaitGroup{} + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + publicAPI, err := public.NewClient(ctx, "localhost", "50051") + require.NoError(t, err) + + wg.Add(5) + // Реализовать тесты логики приложения: + t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent01.Title, resp2.Events[0].Title) + require.Equal(t, testEvent01.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent01.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent01.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Update(ctx, &public.UpdateReq{ID: resp1.ID, Event: &public.Event{ID: resp1.ID, Title: testEvent02.Title, Date: testEvent02.Date, Latency: testEvent02.Latency, Note: testEvent02.Note, UserID: testEvent02.UserID, NotifyTime: testEvent02.NotifyTime}}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.NoError(t, err) + require.Equal(t, 1, len(resp2.Events)) + require.Equal(t, testEvent02.Title, resp2.Events[0].Title) + require.Equal(t, testEvent02.UserID, resp2.Events[0].UserID) + require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds) + require.Equal(t, testEvent02.Note, resp2.Events[0].Note) + }) + + t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + require.Greater(t, resp1.ID, int64(0)) + _, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID}) + require.NoError(t, err) + resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID}) + require.Error(t, err) + require.Nil(t, resp2) + }) + + t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) { + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + resp2, err := publicAPI.Create(ctx, &testEvent02) + require.NoError(t, err) + require.NotEqual(t, resp1.ID, resp2.ID) + + list, err := publicAPI.List(ctx, &empty.Empty{}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1, e2 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + if v.ID==resp2.ID { + e2=true + } + } + require.True(t, e1) + require.True(t, e2) + }) + + t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T){ + defer wg.Done() + resp1, err := publicAPI.Create(ctx, &testEvent01) + require.NoError(t, err) + list, err := publicAPI.GetByDate(ctx,&public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(list.Events), 2) + var e1 bool + for _,v := range list.Events { + if v.ID==resp1.ID { + e1=true + } + } + require.True(t, e1) + }) + + wg.Wait() +} + + +func time2pbtimestamp(t time.Time) *timestamp.Timestamp { + r, err := ptypes.TimestampProto(t) + if err != nil { + log.Fatalf("cant convert Time to Timestamp: %s", err.Error()) + } + return r +} + +func dur2pbduration(t time.Duration) *duration.Duration { + return ptypes.DurationProto(t) +} diff --git a/hw12_13_14_15_calendar/configs/calendar.conf b/hw12_13_14_15_calendar/configs/calendar.conf index 21dc460..e787d79 100644 --- a/hw12_13_14_15_calendar/configs/calendar.conf +++ b/hw12_13_14_15_calendar/configs/calendar.conf @@ -1,13 +1,13 @@ [Grpc] -Address = "0.0.0.0" +Address = "localhost" Port = "50051" [HTTP] -Address = "0.0.0.0" +Address = "localhost" Port = "50052" [API] -Address = "0.0.0.0" +Address = "localhost" Port = "50053" [Logger] diff --git a/hw12_13_14_15_calendar/pkg/api/public/grpcclient.go b/hw12_13_14_15_calendar/pkg/api/public/grpcclient.go index 42523d8..a81ecc9 100644 --- a/hw12_13_14_15_calendar/pkg/api/public/grpcclient.go +++ b/hw12_13_14_15_calendar/pkg/api/public/grpcclient.go @@ -1,14 +1,14 @@ package public import ( + "context" "fmt" - "net" - "google.golang.org/grpc" + "net" ) -func NewClient(addr, port string) (GrpcClient, error) { - conn, err := grpc.Dial(net.JoinHostPort(addr, port), grpc.WithInsecure()) +func NewClient(ctx context.Context, addr, port string) (GrpcClient, error) { + conn, err := grpc.DialContext(ctx, net.JoinHostPort(addr, port), grpc.WithInsecure()) if err != nil { return nil, fmt.Errorf("can't dial GRPC server: %w", err) } diff --git a/hw12_13_14_15_calendar/pkg/api/public/handler.go b/hw12_13_14_15_calendar/pkg/api/public/handler.go index 82c2af7..ff718c2 100644 --- a/hw12_13_14_15_calendar/pkg/api/public/handler.go +++ b/hw12_13_14_15_calendar/pkg/api/public/handler.go @@ -56,21 +56,21 @@ func (s Service) Update(ctx context.Context, e *UpdateReq) (*empty.Empty, error) cid, ce, err := s.buildStorageEventAndID(e) if err != nil { s.App.Logger.Errorf("inconvertible event: %w", err) - return nil, status.Errorf(codes.Internal, "inconvertible") + return &empty.Empty{}, status.Errorf(codes.Internal, "inconvertible") } if s.App.Storage.Update(cid, ce) != nil { s.App.Logger.Errorf("can't update event in storage: %w", err) - return nil, status.Errorf(codes.Internal, "storage error: can't update event") + return &empty.Empty{}, status.Errorf(codes.Internal, "storage error: can't update event") } - return nil, nil + return &empty.Empty{}, nil } func (s Service) Delete(ctx context.Context, e *DeleteReq) (*empty.Empty, error) { if err := s.App.Storage.Delete(event.ID(e.ID)); err != nil { s.App.Logger.Errorf("can't update event in storage: %w", err) - return nil, status.Errorf(codes.Internal, "storage error: can't update event") + return &empty.Empty{}, status.Errorf(codes.Internal, "storage error: can't update event") } - return nil, nil + return &empty.Empty{}, nil } func (s Service) List(ctx context.Context, e *empty.Empty) (*ListResp, error) {