Created
December 21, 2022 11:17
-
-
Save illiafox/7ef964c41d00569e9c08818a4c49d14b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package storages | |
import ( | |
"context" | |
"math/rand" | |
"testing" | |
"github.com/golang/mock/gomock" | |
"github.com/google/uuid" | |
"github.com/illiafox/saga-shop/api/apptrace" | |
"github.com/illiafox/saga-shop/api/protos" | |
"github.com/illiafox/saga-shop/api/protos/mocks" | |
"github.com/illiafox/saga-shop/models" | |
"github.com/sirupsen/logrus" | |
"github.com/sirupsen/logrus/hooks/test" | |
"github.com/stretchr/testify/require" | |
"github.com/stretchr/testify/suite" | |
sdktrace "go.opentelemetry.io/otel/sdk/trace" | |
"go.opentelemetry.io/otel/sdk/trace/tracetest" | |
"go.opentelemetry.io/otel/trace" | |
) | |
func TestOrdersStorage(t *testing.T) { | |
suite.Run(t, new(GrpcClientSuite)) | |
} | |
type GrpcClientSuite struct { | |
suite.Suite | |
// gRPC client | |
storageMocks *mocks.MockOrderServiceClient | |
storage GrpcOrdersStorage | |
// Tracing | |
traceExporter *tracetest.InMemoryExporter | |
tracer trace.Tracer | |
traceProvider *sdktrace.TracerProvider | |
// Logger | |
loggerHook *test.Hook | |
} | |
func (s *GrpcClientSuite) SetupSuite() { | |
ctrl := gomock.NewController(s.T()) | |
s.storageMocks = mocks.NewMockOrderServiceClient(ctrl) | |
// Exporter | |
exp := tracetest.NewInMemoryExporter() | |
s.traceExporter = exp | |
// Provider | |
provider, err := apptrace.NewTraceProvider(exp, "TestService") | |
require.NoError(s.T(), err) | |
s.traceProvider = provider | |
// Tracer | |
tracer := provider.Tracer("TestTracer") | |
s.tracer = tracer | |
// Logger | |
logger, hook := test.NewNullLogger() | |
logger.Level = logrus.DebugLevel | |
s.loggerHook = hook | |
// Storage | |
s.storage = NewGrpcOrderStorage(s.storageMocks, tracer, logger) | |
} | |
func (s *GrpcClientSuite) SetupTest() { | |
// Reset spans storage before each test | |
s.traceExporter.Reset() | |
// Reset logger | |
s.loggerHook.Reset() | |
} | |
func (s *GrpcClientSuite) TearDownTest() { | |
// Flush all spans after the test | |
require.NoError(s.T(), s.traceProvider.ForceFlush(context.Background())) | |
// Get all recorded spans | |
spans := s.traceExporter.GetSpans() | |
require.Len(s.T(), spans, 2) | |
// Check whether the span is inherited from the parent span | |
// spans[1] - parent span | |
// spans[0] - inherited span | |
require.Equal(s.T(), spans[1].SpanContext, spans[0].Parent) | |
// Check debug logs | |
require.Equal(s.T(), 1, len(s.loggerHook.Entries)) | |
require.Equal(s.T(), logrus.DebugLevel, s.loggerHook.LastEntry().Level) | |
} | |
func (s *GrpcClientSuite) Test_PlaceOrder() { | |
// Create expected variables | |
var ( | |
product = models.Product{ | |
ItemID: uuid.New(), | |
Price: rand.Uint64(), | |
Count: rand.Uint64(), | |
} | |
ExpectedUserID = uuid.New() | |
ExpectedOrderID = uuid.New() | |
) | |
// Mocks | |
s.storageMocks.EXPECT(). | |
PlaceOrder(gomock.Any(), &protos.PlaceOrderRequest{ | |
UserId: ExpectedUserID.String(), | |
Products: []*protos.Product{product.ToProto()}, | |
}). | |
Return(&protos.PlaceOrderResponse{ | |
OrderId: ExpectedOrderID.String(), | |
}, nil) | |
// Create new span | |
ctx, span := s.tracer.Start(context.Background(), "TestSpan") | |
defer span.End() | |
// Make call | |
orderID, err := s.storage.PlaceOrder(ctx, ExpectedUserID, []models.Product{product}) | |
require.NoError(s.T(), err) | |
require.Equal(s.T(), ExpectedOrderID, orderID) | |
} | |
func (s *GrpcClientSuite) Test_GetOrderStatus() { | |
statuses := []models.OrderStatus{ | |
models.StatusPendingAcceptance, | |
models.StatusAccepted, | |
models.StatusRejected, | |
} | |
for _, ExpectedStatus := range statuses { | |
// Convert status to proto | |
protoStatus, err := models.OrderStatusToProto(ExpectedStatus) | |
require.NoError(s.T(), err) | |
s.T().Run(protos.OrderStatus_name[int32(protoStatus)], func(t *testing.T) { | |
// Reset logger | |
s.SetupTest() | |
// Check tracer spans | |
defer s.TearDownTest() | |
ExpectedOrderID := uuid.New() | |
ExpectedReason := uuid.NewString() | |
s.storageMocks.EXPECT(). | |
GetOrderStatus(gomock.Any(), &protos.GetOrderStatusRequest{ | |
OrderId: ExpectedOrderID.String(), | |
}). | |
Return(&protos.GetOrderStatusResponse{ | |
OrderStatus: protoStatus, | |
Reason: ExpectedReason, | |
}, nil) | |
// Create new span | |
ctx, span := s.tracer.Start(context.Background(), "TestSpan") | |
defer span.End() | |
// Make call | |
status, reason, err := s.storage.GetOrderStatus(ctx, ExpectedOrderID) | |
require.NoError(s.T(), err) | |
require.Equal(s.T(), ExpectedStatus, status) | |
require.Equal(s.T(), ExpectedReason, reason) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment