diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 00000000..e46df37b --- /dev/null +++ b/.bazelignore @@ -0,0 +1,4 @@ +pkg +bin +.git +.idea diff --git a/.envrc b/.envrc index 96220568..ca63b0de 100644 --- a/.envrc +++ b/.envrc @@ -1,7 +1,4 @@ -GOPATH=$(pwd) -export GOPATH PATH_add tools - -WORKSPACE_ROOT=$(pwd) -export WORKSPACE_ROOT +REPO_ROOT=$(pwd) +export REPO_ROOT diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml new file mode 100644 index 00000000..2dffbca8 --- /dev/null +++ b/.github/workflows/build_and_test.yml @@ -0,0 +1,50 @@ +name: Build and Test + +on: + push: + branches: + - main + pull_request: + types: + - opened + - reopened + - synchronize + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build all services + run: make build + + - name: Run unit tests + run: make test || echo "No tests found yet" + + - name: Start all servers + run: make start-servers + + - name: Run service integration tests + run: make integration-test + + - name: Run end-to-end tests + run: make e2e-test + + - name: Stop servers + if: always() + run: make stop-servers + + - name: Display server logs on failure + if: failure() + run: | + echo "=== Gateway logs ===" + cat /tmp/gateway.log || echo "No gateway logs found" + echo "" + echo "=== Orchestrator logs ===" + cat /tmp/orchestrator.log || echo "No orchestrator logs found" + echo "" + echo "=== Speculator logs ===" + cat /tmp/speculator.log || echo "No speculator logs found" diff --git a/.gitignore b/.gitignore index 1aa0be45..22b0c568 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ MODULE.bazel.lock .vscode/ .idea/ .claude/ +.ijwb/ # Built binaries diff --git a/MODULE.bazel b/MODULE.bazel index d5bee897..508e6a94 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,9 +1,3 @@ -module( - name = "submitqueue", - version = "0.1.0", - bazel_compatibility = [">=7.0.0"], -) - bazel_dep(name = "rules_go", version = "0.57.0") bazel_dep(name = "gazelle", version = "0.45.0") bazel_dep(name = "rules_proto", version = "7.1.0") @@ -37,8 +31,10 @@ go_deps.from_file(go_mod = "//:go.mod") use_repo( go_deps, "com_github_gogo_protobuf", + "com_github_uber_go_tally_v4", "org_golang_google_grpc", "org_golang_google_protobuf", "org_uber_go_fx", "org_uber_go_yarpc", + "org_uber_go_zap", ) diff --git a/Makefile b/Makefile index a5329684..eb04cf6f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: proto build test clean run-gateway run-orchestrator run-speculator run-client-gateway run-client-orchestrator run-client-speculator +.PHONY: proto build test integration-test integration-test-gateway integration-test-orchestrator integration-test-speculator e2e-test gazelle clean run-all start-servers stop-servers run-gateway run-orchestrator run-speculator run-client-gateway run-client-orchestrator run-client-speculator # Bazel wrapper BAZEL = ./tools/bazel @@ -20,19 +20,10 @@ proto: --proto_path=speculator/proto speculator/proto/speculator.proto @echo "Protobuf files generated successfully!" -# Build all services and examples using Bazel +# Build everything in the project using Bazel build: - @echo "Building all services with Bazel..." - @$(BAZEL) build //gateway:gateway - @$(BAZEL) build //orchestrator:orchestrator - @$(BAZEL) build //speculator:speculator - @echo "Building example servers and clients..." - @$(BAZEL) build //examples/server/gateway:gateway - @$(BAZEL) build //examples/server/orchestrator:orchestrator - @$(BAZEL) build //examples/server/speculator:speculator - @$(BAZEL) build //examples/client/gateway:gateway - @$(BAZEL) build //examples/client/orchestrator:orchestrator - @$(BAZEL) build //examples/client/speculator:speculator + @echo "Building all targets with Bazel..." + @$(BAZEL) build //... @echo "Copying binaries to ./bin/..." @mkdir -p bin @cp -f bazel-bin/examples/server/gateway/gateway_/gateway bin/gateway_server 2>/dev/null || \ @@ -49,9 +40,38 @@ build: cp -f bazel-bin/examples/client/speculator/speculator bin/speculator_client 2>/dev/null || true @echo "Build complete! Binaries are in ./bin/" -# Run tests using Bazel +# Run unit tests using Bazel (excludes integration tests which require running servers) test: - @$(BAZEL) test //... + @echo "Running unit tests..." + @$(BAZEL) test //... --test_tag_filters=-manual,-integration || echo "No unit tests found (only integration tests exist)" + +# Generate/update BUILD.bazel files using Gazelle +gazelle: + @echo "Running Gazelle to update BUILD files..." + @$(BAZEL) run //:gazelle + +# Run integration tests for a specific service (requires that service to be running) +integration-test-gateway: + @echo "Running Gateway integration tests..." + @$(BAZEL) test //gateway/integration_tests:integration_test --test_output=all + +integration-test-orchestrator: + @echo "Running Orchestrator integration tests..." + @$(BAZEL) test //orchestrator/integration_tests:integration_test --test_output=all + +integration-test-speculator: + @echo "Running Speculator integration tests..." + @$(BAZEL) test //speculator/integration_tests:integration_test --test_output=all + +# Run all service integration tests (requires all services to be running) +integration-test: + @echo "Running all service integration tests..." + @$(BAZEL) test //gateway/integration_tests:integration_test //orchestrator/integration_tests:integration_test //speculator/integration_tests:integration_test --test_output=all + +# Run end-to-end tests (requires all services to be running) +e2e-test: + @echo "Running end-to-end tests..." + @$(BAZEL) test //integration_tests:e2e_test --test_output=all # Clean generated files and binaries clean: @@ -68,6 +88,39 @@ clean-proto: @rm -rf speculator/protopb/*.pb.go @echo "Proto clean complete!" +# Start all servers in background (for testing) +start-servers: + @echo "Starting all servers in background..." + @./bin/gateway_server > /tmp/gateway.log 2>&1 & echo $$! > /tmp/gateway.pid + @./bin/orchestrator_server > /tmp/orchestrator.log 2>&1 & echo $$! > /tmp/orchestrator.pid + @./bin/speculator_server > /tmp/speculator.log 2>&1 & echo $$! > /tmp/speculator.pid + @sleep 2 + @echo "All servers started:" + @echo " Gateway (PID: $$(cat /tmp/gateway.pid)) - http://localhost:8081" + @echo " Orchestrator (PID: $$(cat /tmp/orchestrator.pid)) - http://localhost:8082" + @echo " Speculator (PID: $$(cat /tmp/speculator.pid)) - http://localhost:8083" + @echo "" + @echo "Logs:" + @echo " tail -f /tmp/gateway.log" + @echo " tail -f /tmp/orchestrator.log" + @echo " tail -f /tmp/speculator.log" + @echo "" + @echo "To stop: make stop-servers" + +# Stop all background servers +stop-servers: + @echo "Stopping all servers..." + @if [ -f /tmp/gateway.pid ]; then kill $$(cat /tmp/gateway.pid) 2>/dev/null || true; rm -f /tmp/gateway.pid; fi + @if [ -f /tmp/orchestrator.pid ]; then kill $$(cat /tmp/orchestrator.pid) 2>/dev/null || true; rm -f /tmp/orchestrator.pid; fi + @if [ -f /tmp/speculator.pid ]; then kill $$(cat /tmp/speculator.pid) 2>/dev/null || true; rm -f /tmp/speculator.pid; fi + @echo "All servers stopped" + +# Run all servers (for testing) - starts servers, waits for Ctrl+C, then stops +run-all: start-servers + @echo "" + @echo "Press Ctrl+C to stop all servers..." + @trap 'make stop-servers' INT; while true; do sleep 1; done + # Run gateway server using Bazel run-gateway: @echo "Starting gateway server on port 8081..." @@ -112,20 +165,44 @@ query-deps: # Help help: @echo "Available targets:" - @echo " make proto - Generate protobuf files (using Bazel)" - @echo " make build - Build all services and examples (using Bazel)" - @echo " make test - Run tests (using Bazel)" + @echo "" + @echo "Build & Test:" + @echo " make proto - Generate protobuf files" + @echo " make build - Build all services and examples" + @echo " make test - Run unit tests" + @echo " make gazelle - Update BUILD.bazel files" @echo " make clean - Clean generated files and binaries" + @echo "" + @echo "Run Servers:" + @echo " make run-all - Run all servers (Ctrl+C to stop)" + @echo " make start-servers - Start all servers in background" + @echo " make stop-servers - Stop all background servers" @echo " make run-gateway - Run gateway server (port 8081)" @echo " make run-orchestrator - Run orchestrator server (port 8082)" @echo " make run-speculator - Run speculator server (port 8083)" - @echo " make run-client-gateway - Run gateway client (use SERVER_ADDR= and MESSAGE=)" + @echo "" + @echo "Integration Tests (requires servers to be running):" + @echo " make integration-test-gateway - Test Gateway service" + @echo " make integration-test-orchestrator - Test Orchestrator service" + @echo " make integration-test-speculator - Test Speculator service" + @echo " make integration-test - Test all services" + @echo " make e2e-test - Run end-to-end tests" + @echo "" + @echo "Run Clients:" + @echo " make run-client-gateway - Run gateway client" @echo " make run-client-orchestrator - Run orchestrator client" @echo " make run-client-speculator - Run speculator client" + @echo "" + @echo "Other:" @echo " make deps - Install Go dependencies" @echo " make query-targets - List all Bazel targets" - @echo " make query-deps - Show dependencies for gateway server" @echo "" @echo "Examples:" + @echo " # Start all servers and run integration tests" + @echo " make build && make start-servers && make integration-test && make stop-servers" + @echo "" + @echo " # Run a single server" @echo " make run-gateway" - @echo " make run-client-gateway SERVER_ADDR=localhost:8081 MESSAGE='hello gateway'" + @echo "" + @echo " # Test with custom message" + @echo " make run-client-gateway MESSAGE='hello gateway'" diff --git a/README.md b/README.md index fb663173..f26d00c1 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ Submit Queue consists of three main services: ## gRPC API Each service has its own proto definitions and exposes its own gRPC API: -- **GatewayService**: Gateway API with Ping method (port 8081) -- **OrchestratorService**: Orchestrator API with Ping method (port 8082) -- **SpeculatorService**: Speculator API with Ping method (port 8083) +- **SubmitQueueGateway**: Gateway API with Ping method (port 8081) +- **SubmitQueueOrchestrator**: Orchestrator API with Ping method (port 8082) +- **SubmitQueueSpeculator**: Speculator API with Ping method (port 8083) ### Quick Start @@ -25,8 +25,11 @@ make run-gateway # Using Go directly go run examples/server/gateway/main.go -# Using Bazel +# Using Bazel (with direnv) bazel run //examples/server/gateway:gateway + +# Or without direnv +./tools/bazel run //examples/server/gateway:gateway ``` Test the service: @@ -38,7 +41,7 @@ make run-client-gateway MESSAGE="hello" go run examples/client/gateway/main.go -message "hello" # Or using grpcurl -grpcurl -plaintext -d '{"message": "hello"}' localhost:8081 uber.devexp.submitqueue.gateway.GatewayService/Ping +grpcurl -plaintext -d '{"message": "hello"}' localhost:8081 uber.devexp.submitqueue.gateway.SubmitQueueGateway/Ping ``` For detailed instructions, see [examples/README.md](examples/README.md). @@ -47,19 +50,54 @@ For detailed instructions, see [examples/README.md](examples/README.md). See [docs/architecture/STRUCTURE.md](docs/architecture/STRUCTURE.md) for a detailed breakdown of the project structure. +## Architecture + +The project follows clean architecture principles with clear separation of concerns: + +- **Controllers** (`core/controller/`): Pure business logic, independent of transport layer + - Only depend on logger, metrics, and protobuf types + - Example: `PingController` handles ping business logic + +- **Server Adapters** (`examples/server/`): gRPC transport layer + - Wrap controllers and implement gRPC service interfaces + - Handle protocol-specific concerns (e.g., `UnimplementedServiceServer`) + +- **Observability**: Built-in logging and metrics + - Structured logging with [Zap](https://github.com/uber-go/zap) + - Metrics collection with [Tally](https://github.com/uber-go/tally) + - Development servers use human-readable console logging + ## Development ### Prerequisites -- **Go 1.24 or later** (required) +- **Go 1.24 or later** (optional, Bazel manages its own Go toolchain) - **protoc** and Go plugins (optional, only needed if modifying proto files) -- **Bazelisk** (optional, for Bazel builds) -- **grpcurl** (optional, for testing) +- **grpcurl** (optional, for manual testing) +- **direnv** (recommended, to automatically load `.envrc`) + +**Note**: The project includes `./tools/bazel` (bazelisk wrapper) and `.bazelversion`, so you don't need to install Bazel or Bazelisk separately. + +#### Using direnv (Recommended) + +Install direnv and allow the `.envrc` file: +```bash +# macOS +brew install direnv + +# Add to your shell profile (~/.zshrc or ~/.bashrc) +eval "$(direnv hook zsh)" # or bash, fish, etc. + +# In the project directory +direnv allow +``` + +With direnv enabled, you can use `bazel` directly instead of `./tools/bazel`. -Install tools (optional): +Install optional tools: ```bash # macOS -brew install protobuf bazelisk grpcurl +brew install protobuf grpcurl # Install Go plugins (only if you need to regenerate proto files) go install google.golang.org/protobuf/cmd/protoc-gen-go@latest @@ -127,16 +165,17 @@ go build -o bin/speculator_client ./examples/client/speculator/ The project uses **Bzlmod** (not WORKSPACE) for dependency management. Bazel version is pinned at 8.4.1 in `.bazelversion`. -```bash -# Install Bazelisk (recommended) -brew install bazelisk +The project includes `./tools/bazel` which automatically downloads the correct Bazel version. If you're using `direnv`, you can simply use `bazel` instead of `./tools/bazel`. -# Build everything +```bash +# Build everything (with direnv) bazel build //... +# Or without direnv +./tools/bazel build //... + # Build specific components bazel build //gateway/protopb -bazel build //gateway:gateway bazel build //examples/server/gateway:gateway bazel build //examples/client/gateway:gateway @@ -146,12 +185,15 @@ bazel run //examples/server/gateway:gateway # Run a client bazel run //examples/client/gateway:gateway -- -message "hello" -# Or use '.' from the directory -cd examples/server/gateway && bazel run . -cd examples/client/gateway && bazel run . -- -message "hello" +# Or use the Makefile (recommended) +make build +make run-gateway ``` -**Note**: The repository uses Bzlmod for modern dependency management. All generated proto files are committed to the repository. +**Note**: +- The repository uses Bzlmod for modern dependency management +- All generated proto files are committed to the repository +- With `direnv` enabled, use `bazel` directly; otherwise use `./tools/bazel` ### Running Services @@ -200,7 +242,8 @@ message PingResponse { string message = 1; string service_name = 2; int64 timestamp = 3; - string hostname = 4; // New field added + string hostname = 4; + string new_field = 5; // New field added } ``` @@ -214,8 +257,8 @@ make proto # - gateway/protopb/gateway_grpc.pb.go # - gateway/protopb/gateway.pb.yarpc.go -# Now update the service implementation -# Edit gateway/core/controller/ping.go to populate the hostname field +# Now update the controller implementation +# Edit gateway/core/controller/ping.go to populate the new field in the PingResponse ``` ### Testing @@ -235,7 +278,7 @@ make proto 3. **Or use grpcurl:** ```bash grpcurl -plaintext -d '{"message": "hello"}' \ - localhost:8081 uber.devexp.submitqueue.gateway.GatewayService/Ping + localhost:8081 uber.devexp.submitqueue.gateway.SubmitQueueGateway/Ping ``` #### Testing All Services @@ -273,7 +316,7 @@ make test 1. **Update the proto file:** ```protobuf // In gateway/proto/gateway.proto - service GatewayService { + service SubmitQueueGateway { rpc Ping(PingRequest) returns (PingResponse) {} rpc NewMethod(NewRequest) returns (NewResponse) {} // Add new method } @@ -287,17 +330,44 @@ make test make proto ``` -3. **Implement the method in the service:** +3. **Implement the method in the controller:** + ```go + // In gateway/core/controller/ (create a new controller file) + type NewController struct { + logger *zap.Logger + metricsScope tally.Scope + } + + func NewNewController(logger *zap.Logger, scope tally.Scope) *NewController { + if logger == nil { + logger = zap.NewNop() + } + if scope == nil { + scope = tally.NoopScope + } + return &NewController{logger: logger, metricsScope: scope} + } + + func (c *NewController) NewMethod(ctx context.Context, req *pb.NewRequest) (*pb.NewResponse, error) { + // Business logic here + c.logger.Info("new method called") + c.metricsScope.Counter("new_method_total").Inc(1) + // ... + } + ``` + +4. **Create server wrapper in example:** ```go - // In gateway/core/controller/ping.go (or create a new file) - func (s *PingServiceImpl) NewMethod(ctx context.Context, req *pb.NewRequest) (*pb.NewResponse, error) { - // Implementation here + // In examples/server/gateway/main.go + // Add method delegation to GatewayServer struct: + func (s *GatewayServer) NewMethod(ctx context.Context, req *pb.NewRequest) (*pb.NewResponse, error) { + return s.newController.NewMethod(ctx, req) } ``` -4. **Update clients to call the new method** +5. **Update clients to call the new method** -5. **Rebuild and test:** +6. **Rebuild and test:** ```bash make build ``` @@ -333,5 +403,6 @@ bazel clean **Bazel build issues:** - Bazel version is pinned to 8.4.1 in `.bazelversion` -- Use `./tools/bazel` wrapper or install bazelisk -- Try `bazel shutdown` and rebuild +- With `direnv`, you can use `bazel` directly; otherwise use `./tools/bazel` +- Try `bazel shutdown` (or `./tools/bazel shutdown`) and rebuild +- The wrapper automatically downloads the correct Bazel version diff --git a/examples/README.md b/examples/README.md index 133f3896..91359c24 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,9 +6,9 @@ This directory contains example gRPC servers and clients for each service in the Each service has its own proto definitions and gRPC API: -- **Gateway**: GatewayService API (port 8081) -- **Orchestrator**: OrchestratorService API (port 8082) -- **Speculator**: SpeculatorService API (port 8083) +- **SubmitQueueGateway**: Gateway API (port 8081) +- **SubmitQueueOrchestrator**: Orchestrator API (port 8082) +- **SubmitQueueSpeculator**: Speculator API (port 8083) ## Building and Running @@ -141,13 +141,13 @@ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest Test the ping service: ```bash # Test gateway (port 8081) -grpcurl -plaintext -d '{"message": "hello"}' localhost:8081 uber.devexp.submitqueue.gateway.GatewayService/Ping +grpcurl -plaintext -d '{"message": "hello"}' localhost:8081 uber.devexp.submitqueue.gateway.SubmitQueueGateway/Ping # Test orchestrator (port 8082) -grpcurl -plaintext -d '{"message": "hello"}' localhost:8082 uber.devexp.submitqueue.orchestrator.OrchestratorService/Ping +grpcurl -plaintext -d '{"message": "hello"}' localhost:8082 uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator/Ping # Test speculator (port 8083) -grpcurl -plaintext -d '{"message": "hello"}' localhost:8083 uber.devexp.submitqueue.speculator.SpeculatorService/Ping +grpcurl -plaintext -d '{"message": "hello"}' localhost:8083 uber.devexp.submitqueue.speculator.SubmitQueueSpeculator/Ping ``` List available services: @@ -159,9 +159,9 @@ grpcurl -plaintext localhost:8083 list Describe a service: ```bash -grpcurl -plaintext localhost:8081 describe uber.devexp.submitqueue.gateway.GatewayService -grpcurl -plaintext localhost:8082 describe uber.devexp.submitqueue.orchestrator.OrchestratorService -grpcurl -plaintext localhost:8083 describe uber.devexp.submitqueue.speculator.SpeculatorService +grpcurl -plaintext localhost:8081 describe uber.devexp.submitqueue.gateway.SubmitQueueGateway +grpcurl -plaintext localhost:8082 describe uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator +grpcurl -plaintext localhost:8083 describe uber.devexp.submitqueue.speculator.SubmitQueueSpeculator ``` ## API Reference @@ -172,17 +172,17 @@ Each service exposes a Ping method with the same request/response structure but #### Gateway Service -**Service**: `uber.devexp.submitqueue.gateway.GatewayService` +**Service**: `uber.devexp.submitqueue.gateway.SubmitQueueGateway` **Proto**: `gateway/proto/gateway.proto` #### Orchestrator Service -**Service**: `uber.devexp.submitqueue.orchestrator.OrchestratorService` +**Service**: `uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator` **Proto**: `orchestrator/proto/orchestrator.proto` #### Speculator Service -**Service**: `uber.devexp.submitqueue.speculator.SpeculatorService` +**Service**: `uber.devexp.submitqueue.speculator.SubmitQueueSpeculator` **Proto**: `speculator/proto/speculator.proto` ### Ping Method @@ -205,7 +205,7 @@ message PingResponse { **Example:** ```bash -grpcurl -plaintext -d '{"message": "test"}' localhost:8081 uber.devexp.submitqueue.gateway.GatewayService/Ping +grpcurl -plaintext -d '{"message": "test"}' localhost:8081 uber.devexp.submitqueue.gateway.SubmitQueueGateway/Ping ``` Expected response: @@ -249,7 +249,7 @@ import ( // Use the clients conn, _ := grpc.NewClient("localhost:8081", grpc.WithTransportCredentials(insecure.NewCredentials())) -client := gatewaypb.NewGatewayServiceClient(conn) +client := gatewaypb.NewSubmitQueueGatewayClient(conn) resp, _ := client.Ping(context.Background(), &gatewaypb.PingRequest{Message: "hello"}) ``` diff --git a/examples/client/gateway/main.go b/examples/client/gateway/main.go index 570ac874..d0e0c6ab 100644 --- a/examples/client/gateway/main.go +++ b/examples/client/gateway/main.go @@ -36,7 +36,7 @@ func run(addr, message string, timeout time.Duration) error { defer conn.Close() // Create a client - client := pb.NewGatewayServiceClient(conn) + client := pb.NewSubmitQueueGatewayClient(conn) // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), timeout) diff --git a/examples/client/orchestrator/main.go b/examples/client/orchestrator/main.go index c715cf8e..8735d338 100644 --- a/examples/client/orchestrator/main.go +++ b/examples/client/orchestrator/main.go @@ -36,7 +36,7 @@ func run(addr, message string, timeout time.Duration) error { defer conn.Close() // Create a client - client := pb.NewOrchestratorServiceClient(conn) + client := pb.NewSubmitQueueOrchestratorClient(conn) // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), timeout) diff --git a/examples/client/speculator/main.go b/examples/client/speculator/main.go index 52abcf4e..67c5e005 100644 --- a/examples/client/speculator/main.go +++ b/examples/client/speculator/main.go @@ -36,7 +36,7 @@ func run(addr, message string, timeout time.Duration) error { defer conn.Close() // Create a client - client := pb.NewSpeculatorServiceClient(conn) + client := pb.NewSubmitQueueSpeculatorClient(conn) // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), timeout) diff --git a/examples/server/gateway/BUILD.bazel b/examples/server/gateway/BUILD.bazel index 10def661..9dd350f9 100644 --- a/examples/server/gateway/BUILD.bazel +++ b/examples/server/gateway/BUILD.bazel @@ -8,8 +8,10 @@ go_library( deps = [ "//gateway/core/controller", "//gateway/protopb", + "@com_github_uber_go_tally_v4//:tally", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//reflection", + "@org_uber_go_zap//:zap", ], ) diff --git a/examples/server/gateway/main.go b/examples/server/gateway/main.go index f478536b..49344528 100644 --- a/examples/server/gateway/main.go +++ b/examples/server/gateway/main.go @@ -1,18 +1,33 @@ package main import ( + "context" "fmt" "net" "os" "os/signal" "syscall" + "time" + "github.com/uber-go/tally/v4" "github.com/uber/submitqueue/gateway/core/controller" pb "github.com/uber/submitqueue/gateway/protopb" + "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) +// GatewayServer wraps the controller and implements the gRPC service interface +type GatewayServer struct { + pb.UnimplementedSubmitQueueGatewayServer + controller *controller.PingController +} + +// Ping delegates to the controller +func (s *GatewayServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + return s.controller.Ping(ctx, req) +} + func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "Failed to start gateway server: %v\n", err) @@ -21,12 +36,37 @@ func main() { } func run() error { + // Initialize development logger (human-readable console output) + logger, err := zap.NewDevelopment() + if err != nil { + return fmt.Errorf("failed to create logger: %w", err) + } + defer logger.Sync() + + // Initialize metrics scope + scope := tally.NewTestScope("gateway", nil) + go func() { + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + for range ticker.C { + snapshot := scope.Snapshot() + logger.Info("metrics snapshot", + zap.Any("counters", snapshot.Counters()), + zap.Any("gauges", snapshot.Gauges()), + zap.Any("timers", snapshot.Timers()), + ) + } + }() + // Create gRPC server grpcServer := grpc.NewServer() - // Register the ping service - pingService := controller.NewPingService() - pb.RegisterGatewayServiceServer(grpcServer, pingService) + // Create ping controller and wrap it for gRPC + pingController := controller.NewPingController(logger, scope) + gatewayServer := &GatewayServer{ + controller: pingController, + } + pb.RegisterSubmitQueueGatewayServer(grpcServer, gatewayServer) // Register reflection service for debugging with grpcurl reflection.Register(grpcServer) diff --git a/examples/server/orchestrator/BUILD.bazel b/examples/server/orchestrator/BUILD.bazel index e98e47a9..c11afe14 100644 --- a/examples/server/orchestrator/BUILD.bazel +++ b/examples/server/orchestrator/BUILD.bazel @@ -8,8 +8,10 @@ go_library( deps = [ "//orchestrator/core/controller", "//orchestrator/protopb", + "@com_github_uber_go_tally_v4//:tally", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//reflection", + "@org_uber_go_zap//:zap", ], ) diff --git a/examples/server/orchestrator/main.go b/examples/server/orchestrator/main.go index 558cd7e4..68f9d3b8 100644 --- a/examples/server/orchestrator/main.go +++ b/examples/server/orchestrator/main.go @@ -1,18 +1,33 @@ package main import ( + "context" "fmt" "net" "os" "os/signal" "syscall" + "time" + "github.com/uber-go/tally/v4" "github.com/uber/submitqueue/orchestrator/core/controller" pb "github.com/uber/submitqueue/orchestrator/protopb" + "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) +// OrchestratorServer wraps the controller and implements the gRPC service interface +type OrchestratorServer struct { + pb.UnimplementedSubmitQueueOrchestratorServer + controller *controller.PingController +} + +// Ping delegates to the controller +func (s *OrchestratorServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + return s.controller.Ping(ctx, req) +} + func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "Failed to start orchestrator server: %v\n", err) @@ -21,12 +36,37 @@ func main() { } func run() error { + // Initialize development logger (human-readable console output) + logger, err := zap.NewDevelopment() + if err != nil { + return fmt.Errorf("failed to create logger: %w", err) + } + defer logger.Sync() + + // Initialize metrics scope + scope := tally.NewTestScope("orchestrator", nil) + go func() { + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + for range ticker.C { + snapshot := scope.Snapshot() + logger.Info("metrics snapshot", + zap.Any("counters", snapshot.Counters()), + zap.Any("gauges", snapshot.Gauges()), + zap.Any("timers", snapshot.Timers()), + ) + } + }() + // Create gRPC server grpcServer := grpc.NewServer() - // Register the ping service - pingService := controller.NewPingService() - pb.RegisterOrchestratorServiceServer(grpcServer, pingService) + // Create ping controller and wrap it for gRPC + pingController := controller.NewPingController(logger, scope) + orchestratorServer := &OrchestratorServer{ + controller: pingController, + } + pb.RegisterSubmitQueueOrchestratorServer(grpcServer, orchestratorServer) // Register reflection service for debugging with grpcurl reflection.Register(grpcServer) diff --git a/examples/server/speculator/BUILD.bazel b/examples/server/speculator/BUILD.bazel index c773bd34..d6fc9e7c 100644 --- a/examples/server/speculator/BUILD.bazel +++ b/examples/server/speculator/BUILD.bazel @@ -8,8 +8,10 @@ go_library( deps = [ "//speculator/core/controller", "//speculator/protopb", + "@com_github_uber_go_tally_v4//:tally", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//reflection", + "@org_uber_go_zap//:zap", ], ) diff --git a/examples/server/speculator/main.go b/examples/server/speculator/main.go index e50c4211..0db02c6d 100644 --- a/examples/server/speculator/main.go +++ b/examples/server/speculator/main.go @@ -1,18 +1,33 @@ package main import ( + "context" "fmt" "net" "os" "os/signal" "syscall" + "time" + "github.com/uber-go/tally/v4" "github.com/uber/submitqueue/speculator/core/controller" pb "github.com/uber/submitqueue/speculator/protopb" + "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) +// SpeculatorServer wraps the controller and implements the gRPC service interface +type SpeculatorServer struct { + pb.UnimplementedSubmitQueueSpeculatorServer + controller *controller.PingController +} + +// Ping delegates to the controller +func (s *SpeculatorServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + return s.controller.Ping(ctx, req) +} + func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "Failed to start speculator server: %v\n", err) @@ -21,12 +36,37 @@ func main() { } func run() error { + // Initialize development logger (human-readable console output) + logger, err := zap.NewDevelopment() + if err != nil { + return fmt.Errorf("failed to create logger: %w", err) + } + defer logger.Sync() + + // Initialize metrics scope + scope := tally.NewTestScope("speculator", nil) + go func() { + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + for range ticker.C { + snapshot := scope.Snapshot() + logger.Info("metrics snapshot", + zap.Any("counters", snapshot.Counters()), + zap.Any("gauges", snapshot.Gauges()), + zap.Any("timers", snapshot.Timers()), + ) + } + }() + // Create gRPC server grpcServer := grpc.NewServer() - // Register the ping service - pingService := controller.NewPingService() - pb.RegisterSpeculatorServiceServer(grpcServer, pingService) + // Create ping controller and wrap it for gRPC + pingController := controller.NewPingController(logger, scope) + speculatorServer := &SpeculatorServer{ + controller: pingController, + } + pb.RegisterSubmitQueueSpeculatorServer(grpcServer, speculatorServer) // Register reflection service for debugging with grpcurl reflection.Register(grpcServer) diff --git a/gateway/BUILD.bazel b/gateway/BUILD.bazel deleted file mode 100644 index 2c7df90a..00000000 --- a/gateway/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@rules_go//go:def.bzl", "go_library") - -go_library( - name = "gateway", - srcs = [], - importpath = "github.com/uber/submitqueue/gateway", - visibility = ["//visibility:public"], - deps = [ - "//gateway/core/controller", - "//gateway/protopb", - ], -) diff --git a/gateway/core/controller/BUILD.bazel b/gateway/core/controller/BUILD.bazel index aa14b956..de807fc0 100644 --- a/gateway/core/controller/BUILD.bazel +++ b/gateway/core/controller/BUILD.bazel @@ -1,9 +1,24 @@ -load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "controller", srcs = ["ping.go"], importpath = "github.com/uber/submitqueue/gateway/core/controller", visibility = ["//visibility:public"], - deps = ["//gateway/protopb"], + deps = [ + "//gateway/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "controller_test", + srcs = ["ping_test.go"], + embed = [":controller"], + deps = [ + "//gateway/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], ) diff --git a/gateway/core/controller/ping.go b/gateway/core/controller/ping.go index e2bed0ac..7f7977f9 100644 --- a/gateway/core/controller/ping.go +++ b/gateway/core/controller/ping.go @@ -5,28 +5,57 @@ import ( "os" "time" + "github.com/uber-go/tally/v4" pb "github.com/uber/submitqueue/gateway/protopb" + "go.uber.org/zap" ) -// PingServiceImpl implements the GatewayService gRPC service for the gateway -type PingServiceImpl struct { - pb.UnimplementedGatewayServiceServer +// PingController handles ping business logic for the gateway +type PingController struct { + logger *zap.Logger + metricsScope tally.Scope } -// NewPingService creates a new instance of the gateway ping service -func NewPingService() *PingServiceImpl { - return &PingServiceImpl{} +// NewPingController creates a new instance of the gateway ping controller +func NewPingController(logger *zap.Logger, scope tally.Scope) *PingController { + if logger == nil { + logger = zap.NewNop() + } + if scope == nil { + scope = tally.NoopScope + } + + return &PingController{ + logger: logger, + metricsScope: scope, + } } // Ping handles the ping request and returns a response -func (s *PingServiceImpl) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { +func (c *PingController) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + start := time.Now() + defer func() { + c.metricsScope.Timer("ping_latency").Record(time.Since(start)) + }() + + c.metricsScope.Counter("ping_requests_total").Inc(1) + message := "pong" + isEcho := false if req.Message != "" { message = "echo: " + req.Message + isEcho = true + c.metricsScope.Counter("echo_requests_total").Inc(1) } hostname, _ := os.Hostname() + c.logger.Info("ping request received", + zap.String("message", req.Message), + zap.Bool("is_echo", isEcho), + zap.String("hostname", hostname), + ) + return &pb.PingResponse{ Message: message, ServiceName: "gateway", diff --git a/gateway/core/controller/ping_test.go b/gateway/core/controller/ping_test.go new file mode 100644 index 00000000..5ff713bd --- /dev/null +++ b/gateway/core/controller/ping_test.go @@ -0,0 +1,114 @@ +package controller + +import ( + "context" + "testing" + "time" + + pb "github.com/uber/submitqueue/gateway/protopb" +) + +func TestNewPingController(t *testing.T) { + controller := NewPingController(nil, nil) + if controller == nil { + t.Fatal("NewPingController() returned nil") + } +} + +func TestPing_DefaultMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != "pong" { + t.Errorf("Expected message 'pong', got '%s'", resp.Message) + } +} + +func TestPing_CustomMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + testCases := []struct { + name string + input string + expected string + }{ + {"simple message", "hello", "echo: hello"}, + {"message with spaces", "hello world", "echo: hello world"}, + {"special characters", "test!@#", "echo: test!@#"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + req := &pb.PingRequest{Message: tc.input} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != tc.expected { + t.Errorf("Expected message '%s', got '%s'", tc.expected, resp.Message) + } + }) + } +} + +func TestPing_ServiceName(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.ServiceName != "gateway" { + t.Errorf("Expected service name 'gateway', got '%s'", resp.ServiceName) + } +} + +func TestPing_Timestamp(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + before := time.Now().Unix() + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + after := time.Now().Unix() + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Timestamp < before || resp.Timestamp > after { + t.Errorf("Timestamp %d is not within expected range [%d, %d]", resp.Timestamp, before, after) + } +} + +func TestPing_Hostname(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + // Hostname should be set (non-empty string) + // We don't check the exact value as it depends on the environment + if resp.Hostname == "" { + t.Error("Expected hostname to be set, got empty string") + } +} diff --git a/gateway/integration_tests/BUILD.bazel b/gateway/integration_tests/BUILD.bazel new file mode 100644 index 00000000..10df327e --- /dev/null +++ b/gateway/integration_tests/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_test") + +go_test( + name = "integration_test", + srcs = ["ping_test.go"], + tags = [ + "integration", + "manual", + ], + deps = [ + "//gateway/protopb", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], +) diff --git a/gateway/integration_tests/ping_test.go b/gateway/integration_tests/ping_test.go new file mode 100644 index 00000000..862cbf40 --- /dev/null +++ b/gateway/integration_tests/ping_test.go @@ -0,0 +1,102 @@ +package gateway_test + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + pb "github.com/uber/submitqueue/gateway/protopb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + defaultTimeout = 5 * time.Second + serverReadyTimeout = 30 * time.Second + retryInterval = 500 * time.Millisecond +) + +// TestPingAPI tests the Gateway service Ping API +func TestPingAPI(t *testing.T) { + addr := getEnvOrDefault("GATEWAY_ADDR", "localhost:8081") + + // Wait for server to be ready + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Gateway server not ready: %v", err) + } + defer conn.Close() + + client := pb.NewSubmitQueueGatewayClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + // Test Ping API + req := &pb.PingRequest{ + Message: "integration test", + } + + resp, err := client.Ping(ctx, req) + if err != nil { + t.Fatalf("Ping failed: %v", err) + } + + // Validate response + if resp.Message == "" { + t.Error("Response message is empty") + } + if resp.ServiceName != "gateway" { + t.Errorf("Expected service name 'gateway', got '%s'", resp.ServiceName) + } + if resp.Timestamp == 0 { + t.Error("Timestamp is zero") + } + if resp.Hostname == "" { + t.Error("Hostname is empty") + } + + t.Logf("Gateway Ping test passed:") + t.Logf(" Message: %s", resp.Message) + t.Logf(" Service: %s", resp.ServiceName) + t.Logf(" Timestamp: %d", resp.Timestamp) + t.Logf(" Hostname: %s", resp.Hostname) +} + +// waitForServer waits for a gRPC server to become ready +func waitForServer(t *testing.T, addr string, timeout time.Duration) (*grpc.ClientConn, error) { + t.Helper() + + deadline := time.Now().Add(timeout) + var lastErr error + + for time.Now().Before(deadline) { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + conn, err := grpc.DialContext( + ctx, + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + cancel() + + if err == nil { + t.Logf("Server at %s is ready", addr) + return conn, nil + } + + lastErr = err + time.Sleep(retryInterval) + } + + return nil, fmt.Errorf("server at %s not ready after %v: %w", addr, timeout, lastErr) +} + +// getEnvOrDefault returns the value of an environment variable or a default value +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/gateway/proto/BUILD.bazel b/gateway/proto/BUILD.bazel index 80d0c2a0..3aab896d 100644 --- a/gateway/proto/BUILD.bazel +++ b/gateway/proto/BUILD.bazel @@ -26,3 +26,10 @@ go_library( importpath = "github.com/uber/submitqueue/gateway/proto", visibility = ["//visibility:public"], ) + +go_library( + name = "protopb", + embed = [":gatewaypb_go_proto"], + importpath = "github.com/uber/submitqueue/gateway/protopb", + visibility = ["//visibility:public"], +) diff --git a/gateway/proto/gateway.proto b/gateway/proto/gateway.proto index 99cbf3ca..5088e722 100644 --- a/gateway/proto/gateway.proto +++ b/gateway/proto/gateway.proto @@ -25,8 +25,8 @@ message PingResponse { string hostname = 4; } -// GatewayService provides the gateway API -service GatewayService { +// SubmitQueueGateway provides the gateway API +service SubmitQueueGateway { // Ping returns a response indicating the service is alive rpc Ping(PingRequest) returns (PingResponse) {} } diff --git a/gateway/protopb/BUILD.bazel b/gateway/protopb/BUILD.bazel index 8c0c94b5..841c6930 100644 --- a/gateway/protopb/BUILD.bazel +++ b/gateway/protopb/BUILD.bazel @@ -4,8 +4,8 @@ go_library( name = "protopb", srcs = [ "gateway.pb.go", - "gateway_grpc.pb.go", "gateway.pb.yarpc.go", + "gateway_grpc.pb.go", ], importpath = "github.com/uber/submitqueue/gateway/protopb", visibility = ["//visibility:public"], diff --git a/gateway/protopb/gateway.pb.go b/gateway/protopb/gateway.pb.go index 3592d325..08c4db59 100644 --- a/gateway/protopb/gateway.pb.go +++ b/gateway/protopb/gateway.pb.go @@ -151,8 +151,8 @@ const file_gateway_proto_rawDesc = "" + "\amessage\x18\x01 \x01(\tR\amessage\x12!\n" + "\fservice_name\x18\x02 \x01(\tR\vserviceName\x12\x1c\n" + "\ttimestamp\x18\x03 \x01(\x03R\ttimestamp\x12\x1a\n" + - "\bhostname\x18\x04 \x01(\tR\bhostname2w\n" + - "\x0eGatewayService\x12e\n" + + "\bhostname\x18\x04 \x01(\tR\bhostname2{\n" + + "\x12SubmitQueueGateway\x12e\n" + "\x04Ping\x12,.uber.devexp.submitqueue.gateway.PingRequest\x1a-.uber.devexp.submitqueue.gateway.PingResponse\"\x00Bb\n" + "#com.uber.devexp.submitqueue.gatewayB\fGatewayProtoP\x01Z+github.com/uber/submitqueue/gateway/protopbb\x06proto3" @@ -174,8 +174,8 @@ var file_gateway_proto_goTypes = []any{ (*PingResponse)(nil), // 1: uber.devexp.submitqueue.gateway.PingResponse } var file_gateway_proto_depIdxs = []int32{ - 0, // 0: uber.devexp.submitqueue.gateway.GatewayService.Ping:input_type -> uber.devexp.submitqueue.gateway.PingRequest - 1, // 1: uber.devexp.submitqueue.gateway.GatewayService.Ping:output_type -> uber.devexp.submitqueue.gateway.PingResponse + 0, // 0: uber.devexp.submitqueue.gateway.SubmitQueueGateway.Ping:input_type -> uber.devexp.submitqueue.gateway.PingRequest + 1, // 1: uber.devexp.submitqueue.gateway.SubmitQueueGateway.Ping:output_type -> uber.devexp.submitqueue.gateway.PingResponse 1, // [1:2] is the sub-list for method output_type 0, // [0:1] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name diff --git a/gateway/protopb/gateway.pb.yarpc.go b/gateway/protopb/gateway.pb.yarpc.go index 3ebef060..002dd349 100644 --- a/gateway/protopb/gateway.pb.yarpc.go +++ b/gateway/protopb/gateway.pb.yarpc.go @@ -20,15 +20,15 @@ import ( var _ = ioutil.NopCloser -// GatewayServiceYARPCClient is the YARPC client-side interface for the GatewayService service. -type GatewayServiceYARPCClient interface { +// SubmitQueueGatewayYARPCClient is the YARPC client-side interface for the SubmitQueueGateway service. +type SubmitQueueGatewayYARPCClient interface { Ping(context.Context, *PingRequest, ...yarpc.CallOption) (*PingResponse, error) } -func newGatewayServiceYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) GatewayServiceYARPCClient { - return &_GatewayServiceYARPCCaller{protobuf.NewStreamClient( +func newSubmitQueueGatewayYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) SubmitQueueGatewayYARPCClient { + return &_SubmitQueueGatewayYARPCCaller{protobuf.NewStreamClient( protobuf.ClientParams{ - ServiceName: "uber.devexp.submitqueue.gateway.GatewayService", + ServiceName: "uber.devexp.submitqueue.gateway.SubmitQueueGateway", ClientConfig: clientConfig, AnyResolver: anyResolver, Options: options, @@ -36,33 +36,33 @@ func newGatewayServiceYARPCClient(clientConfig transport.ClientConfig, anyResolv )} } -// NewGatewayServiceYARPCClient builds a new YARPC client for the GatewayService service. -func NewGatewayServiceYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) GatewayServiceYARPCClient { - return newGatewayServiceYARPCClient(clientConfig, nil, options...) +// NewSubmitQueueGatewayYARPCClient builds a new YARPC client for the SubmitQueueGateway service. +func NewSubmitQueueGatewayYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) SubmitQueueGatewayYARPCClient { + return newSubmitQueueGatewayYARPCClient(clientConfig, nil, options...) } -// GatewayServiceYARPCServer is the YARPC server-side interface for the GatewayService service. -type GatewayServiceYARPCServer interface { +// SubmitQueueGatewayYARPCServer is the YARPC server-side interface for the SubmitQueueGateway service. +type SubmitQueueGatewayYARPCServer interface { Ping(context.Context, *PingRequest) (*PingResponse, error) } -type buildGatewayServiceYARPCProceduresParams struct { - Server GatewayServiceYARPCServer +type buildSubmitQueueGatewayYARPCProceduresParams struct { + Server SubmitQueueGatewayYARPCServer AnyResolver jsonpb.AnyResolver } -func buildGatewayServiceYARPCProcedures(params buildGatewayServiceYARPCProceduresParams) []transport.Procedure { - handler := &_GatewayServiceYARPCHandler{params.Server} +func buildSubmitQueueGatewayYARPCProcedures(params buildSubmitQueueGatewayYARPCProceduresParams) []transport.Procedure { + handler := &_SubmitQueueGatewayYARPCHandler{params.Server} return protobuf.BuildProcedures( protobuf.BuildProceduresParams{ - ServiceName: "uber.devexp.submitqueue.gateway.GatewayService", + ServiceName: "uber.devexp.submitqueue.gateway.SubmitQueueGateway", UnaryHandlerParams: []protobuf.BuildProceduresUnaryHandlerParams{ { MethodName: "Ping", Handler: protobuf.NewUnaryHandler( protobuf.UnaryHandlerParams{ Handle: handler.Ping, - NewRequest: newGatewayServiceServicePingYARPCRequest, + NewRequest: newSubmitQueueGatewayServicePingYARPCRequest, AnyResolver: params.AnyResolver, }, ), @@ -74,16 +74,16 @@ func buildGatewayServiceYARPCProcedures(params buildGatewayServiceYARPCProcedure ) } -// BuildGatewayServiceYARPCProcedures prepares an implementation of the GatewayService service for YARPC registration. -func BuildGatewayServiceYARPCProcedures(server GatewayServiceYARPCServer) []transport.Procedure { - return buildGatewayServiceYARPCProcedures(buildGatewayServiceYARPCProceduresParams{Server: server}) +// BuildSubmitQueueGatewayYARPCProcedures prepares an implementation of the SubmitQueueGateway service for YARPC registration. +func BuildSubmitQueueGatewayYARPCProcedures(server SubmitQueueGatewayYARPCServer) []transport.Procedure { + return buildSubmitQueueGatewayYARPCProcedures(buildSubmitQueueGatewayYARPCProceduresParams{Server: server}) } -// FxGatewayServiceYARPCClientParams defines the input -// for NewFxGatewayServiceYARPCClient. It provides the -// paramaters to get a GatewayServiceYARPCClient in an +// FxSubmitQueueGatewayYARPCClientParams defines the input +// for NewFxSubmitQueueGatewayYARPCClient. It provides the +// paramaters to get a SubmitQueueGatewayYARPCClient in an // Fx application. -type FxGatewayServiceYARPCClientParams struct { +type FxSubmitQueueGatewayYARPCClientParams struct { fx.In Provider yarpc.ClientConfig @@ -91,28 +91,28 @@ type FxGatewayServiceYARPCClientParams struct { Restriction restriction.Checker `optional:"true"` } -// FxGatewayServiceYARPCClientResult defines the output -// of NewFxGatewayServiceYARPCClient. It provides a -// GatewayServiceYARPCClient to an Fx application. -type FxGatewayServiceYARPCClientResult struct { +// FxSubmitQueueGatewayYARPCClientResult defines the output +// of NewFxSubmitQueueGatewayYARPCClient. It provides a +// SubmitQueueGatewayYARPCClient to an Fx application. +type FxSubmitQueueGatewayYARPCClientResult struct { fx.Out - Client GatewayServiceYARPCClient + Client SubmitQueueGatewayYARPCClient // We are using an fx.Out struct here instead of just returning a client // so that we can add more values or add named versions of the client in // the future without breaking any existing code. } -// NewFxGatewayServiceYARPCClient provides a GatewayServiceYARPCClient +// NewFxSubmitQueueGatewayYARPCClient provides a SubmitQueueGatewayYARPCClient // to an Fx application using the given name for routing. // // fx.Provide( -// protopb.NewFxGatewayServiceYARPCClient("service-name"), +// protopb.NewFxSubmitQueueGatewayYARPCClient("service-name"), // ... // ) -func NewFxGatewayServiceYARPCClient(name string, options ...protobuf.ClientOption) interface{} { - return func(params FxGatewayServiceYARPCClientParams) FxGatewayServiceYARPCClientResult { +func NewFxSubmitQueueGatewayYARPCClient(name string, options ...protobuf.ClientOption) interface{} { + return func(params FxSubmitQueueGatewayYARPCClientParams) FxSubmitQueueGatewayYARPCClientResult { cc := params.Provider.ClientConfig(name) if params.Restriction != nil { @@ -123,91 +123,91 @@ func NewFxGatewayServiceYARPCClient(name string, options ...protobuf.ClientOptio } } - return FxGatewayServiceYARPCClientResult{ - Client: newGatewayServiceYARPCClient(cc, params.AnyResolver, options...), + return FxSubmitQueueGatewayYARPCClientResult{ + Client: newSubmitQueueGatewayYARPCClient(cc, params.AnyResolver, options...), } } } -// FxGatewayServiceYARPCProceduresParams defines the input -// for NewFxGatewayServiceYARPCProcedures. It provides the -// paramaters to get GatewayServiceYARPCServer procedures in an +// FxSubmitQueueGatewayYARPCProceduresParams defines the input +// for NewFxSubmitQueueGatewayYARPCProcedures. It provides the +// paramaters to get SubmitQueueGatewayYARPCServer procedures in an // Fx application. -type FxGatewayServiceYARPCProceduresParams struct { +type FxSubmitQueueGatewayYARPCProceduresParams struct { fx.In - Server GatewayServiceYARPCServer + Server SubmitQueueGatewayYARPCServer AnyResolver jsonpb.AnyResolver `name:"yarpcfx" optional:"true"` } -// FxGatewayServiceYARPCProceduresResult defines the output -// of NewFxGatewayServiceYARPCProcedures. It provides -// GatewayServiceYARPCServer procedures to an Fx application. +// FxSubmitQueueGatewayYARPCProceduresResult defines the output +// of NewFxSubmitQueueGatewayYARPCProcedures. It provides +// SubmitQueueGatewayYARPCServer procedures to an Fx application. // // The procedures are provided to the "yarpcfx" value group. // Dig 1.2 or newer must be used for this feature to work. -type FxGatewayServiceYARPCProceduresResult struct { +type FxSubmitQueueGatewayYARPCProceduresResult struct { fx.Out Procedures []transport.Procedure `group:"yarpcfx"` ReflectionMeta reflection.ServerMeta `group:"yarpcfx"` } -// NewFxGatewayServiceYARPCProcedures provides GatewayServiceYARPCServer procedures to an Fx application. -// It expects a GatewayServiceYARPCServer to be present in the container. +// NewFxSubmitQueueGatewayYARPCProcedures provides SubmitQueueGatewayYARPCServer procedures to an Fx application. +// It expects a SubmitQueueGatewayYARPCServer to be present in the container. // // fx.Provide( -// protopb.NewFxGatewayServiceYARPCProcedures(), +// protopb.NewFxSubmitQueueGatewayYARPCProcedures(), // ... // ) -func NewFxGatewayServiceYARPCProcedures() interface{} { - return func(params FxGatewayServiceYARPCProceduresParams) FxGatewayServiceYARPCProceduresResult { - return FxGatewayServiceYARPCProceduresResult{ - Procedures: buildGatewayServiceYARPCProcedures(buildGatewayServiceYARPCProceduresParams{ +func NewFxSubmitQueueGatewayYARPCProcedures() interface{} { + return func(params FxSubmitQueueGatewayYARPCProceduresParams) FxSubmitQueueGatewayYARPCProceduresResult { + return FxSubmitQueueGatewayYARPCProceduresResult{ + Procedures: buildSubmitQueueGatewayYARPCProcedures(buildSubmitQueueGatewayYARPCProceduresParams{ Server: params.Server, AnyResolver: params.AnyResolver, }), - ReflectionMeta: GatewayServiceReflectionMeta, + ReflectionMeta: SubmitQueueGatewayReflectionMeta, } } } -// GatewayServiceReflectionMeta is the reflection server metadata +// SubmitQueueGatewayReflectionMeta is the reflection server metadata // required for using the gRPC reflection protocol with YARPC. // // See https://github.com/grpc/grpc/blob/master/doc/server-reflection.md. -var GatewayServiceReflectionMeta = reflection.ServerMeta{ - ServiceName: "uber.devexp.submitqueue.gateway.GatewayService", +var SubmitQueueGatewayReflectionMeta = reflection.ServerMeta{ + ServiceName: "uber.devexp.submitqueue.gateway.SubmitQueueGateway", FileDescriptors: yarpcFileDescriptorClosuref1a937782ebbded5, } -type _GatewayServiceYARPCCaller struct { +type _SubmitQueueGatewayYARPCCaller struct { streamClient protobuf.StreamClient } -func (c *_GatewayServiceYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { - responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newGatewayServiceServicePingYARPCResponse, options...) +func (c *_SubmitQueueGatewayYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { + responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newSubmitQueueGatewayServicePingYARPCResponse, options...) if responseMessage == nil { return nil, err } response, ok := responseMessage.(*PingResponse) if !ok { - return nil, protobuf.CastError(emptyGatewayServiceServicePingYARPCResponse, responseMessage) + return nil, protobuf.CastError(emptySubmitQueueGatewayServicePingYARPCResponse, responseMessage) } return response, err } -type _GatewayServiceYARPCHandler struct { - server GatewayServiceYARPCServer +type _SubmitQueueGatewayYARPCHandler struct { + server SubmitQueueGatewayYARPCServer } -func (h *_GatewayServiceYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { +func (h *_SubmitQueueGatewayYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { var request *PingRequest var ok bool if requestMessage != nil { request, ok = requestMessage.(*PingRequest) if !ok { - return nil, protobuf.CastError(emptyGatewayServiceServicePingYARPCRequest, requestMessage) + return nil, protobuf.CastError(emptySubmitQueueGatewayServicePingYARPCRequest, requestMessage) } } response, err := h.server.Ping(ctx, request) @@ -217,46 +217,46 @@ func (h *_GatewayServiceYARPCHandler) Ping(ctx context.Context, requestMessage p return response, err } -func newGatewayServiceServicePingYARPCRequest() proto.Message { +func newSubmitQueueGatewayServicePingYARPCRequest() proto.Message { return &PingRequest{} } -func newGatewayServiceServicePingYARPCResponse() proto.Message { +func newSubmitQueueGatewayServicePingYARPCResponse() proto.Message { return &PingResponse{} } var ( - emptyGatewayServiceServicePingYARPCRequest = &PingRequest{} - emptyGatewayServiceServicePingYARPCResponse = &PingResponse{} + emptySubmitQueueGatewayServicePingYARPCRequest = &PingRequest{} + emptySubmitQueueGatewayServicePingYARPCResponse = &PingResponse{} ) var yarpcFileDescriptorClosuref1a937782ebbded5 = [][]byte{ // gateway.proto []byte{ - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x31, 0x4f, 0xc3, 0x30, - 0x10, 0x85, 0x31, 0xad, 0x80, 0x5e, 0x03, 0x83, 0xa7, 0xa8, 0x42, 0xa2, 0x84, 0x81, 0x4a, 0x80, - 0x23, 0xc1, 0x3f, 0xe8, 0xc2, 0x86, 0xa2, 0xb0, 0xb1, 0x20, 0x3b, 0x9c, 0x52, 0x0f, 0x8e, 0xdd, - 0x9c, 0xdd, 0xc2, 0x0f, 0xe0, 0x7f, 0xa3, 0x38, 0x01, 0xba, 0xa0, 0xb2, 0xf9, 0x9e, 0xdf, 0x67, - 0xbd, 0xe7, 0x83, 0xd3, 0x5a, 0x7a, 0xdc, 0xca, 0x0f, 0xe1, 0x5a, 0xeb, 0x2d, 0xbf, 0x08, 0x0a, - 0x5b, 0xf1, 0x86, 0x1b, 0x7c, 0x77, 0x82, 0x82, 0x32, 0xda, 0xaf, 0x03, 0x06, 0x14, 0x83, 0x2d, - 0xbb, 0x86, 0x69, 0xa1, 0x9b, 0xba, 0xc4, 0x75, 0x40, 0xf2, 0x3c, 0x85, 0x63, 0x83, 0x44, 0xb2, - 0xc6, 0x94, 0xcd, 0xd9, 0x62, 0x52, 0x7e, 0x8f, 0xd9, 0x27, 0x83, 0xa4, 0x77, 0x92, 0xb3, 0x0d, - 0xe1, 0xdf, 0x56, 0x7e, 0x09, 0x09, 0x61, 0xbb, 0xd1, 0x15, 0xbe, 0x36, 0xd2, 0x60, 0x7a, 0x18, - 0xaf, 0xa7, 0x83, 0xf6, 0x24, 0x0d, 0xf2, 0x73, 0x98, 0x78, 0x6d, 0x90, 0xbc, 0x34, 0x2e, 0x1d, - 0xcd, 0xd9, 0x62, 0x54, 0xfe, 0x0a, 0x7c, 0x06, 0x27, 0x2b, 0x4b, 0x3e, 0xc2, 0xe3, 0x08, 0xff, - 0xcc, 0xf7, 0x5b, 0x38, 0x7b, 0xec, 0xb3, 0x3f, 0xf7, 0xef, 0x71, 0x84, 0x71, 0x17, 0x8c, 0xdf, - 0x8a, 0x3d, 0x65, 0xc5, 0x4e, 0xd3, 0xd9, 0xdd, 0x3f, 0xdd, 0x7d, 0xdb, 0xec, 0x60, 0xa9, 0xe0, - 0xaa, 0xb2, 0x66, 0x1f, 0xb5, 0x4c, 0x86, 0x74, 0x45, 0xf7, 0xff, 0x05, 0x7b, 0xb9, 0xa9, 0xb5, - 0x5f, 0x05, 0x25, 0x2a, 0x6b, 0xf2, 0x8e, 0xcd, 0x77, 0xa0, 0x7c, 0x80, 0xf2, 0xb8, 0x2c, 0xa7, - 0xd4, 0x51, 0x3c, 0x3c, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x24, 0x31, 0x64, 0xc6, 0x01, - 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xb1, 0x4e, 0xc3, 0x30, + 0x10, 0x86, 0x31, 0xad, 0x80, 0x5e, 0xc3, 0xe2, 0x29, 0xaa, 0x90, 0x28, 0x61, 0xa0, 0x12, 0xe0, + 0x48, 0xf0, 0x06, 0x5d, 0xd8, 0x50, 0x08, 0x1b, 0x0b, 0xb2, 0xc3, 0x29, 0xf5, 0xe0, 0xd8, 0xcd, + 0xd9, 0x05, 0xc4, 0xcc, 0x7b, 0xa3, 0x38, 0x01, 0xba, 0xa0, 0xb2, 0xf9, 0xce, 0xff, 0x27, 0xdd, + 0xa7, 0x1f, 0x8e, 0x6b, 0xe9, 0xf1, 0x55, 0xbe, 0x0b, 0xd7, 0x5a, 0x6f, 0xf9, 0x69, 0x50, 0xd8, + 0x8a, 0x17, 0xdc, 0xe0, 0x9b, 0x13, 0x14, 0x94, 0xd1, 0x7e, 0x1d, 0x30, 0xa0, 0x18, 0x62, 0xd9, + 0x05, 0x4c, 0x0b, 0xdd, 0xd4, 0x25, 0xae, 0x03, 0x92, 0xe7, 0x29, 0x1c, 0x1a, 0x24, 0x92, 0x35, + 0xa6, 0x6c, 0xce, 0x16, 0x93, 0xf2, 0x7b, 0xcc, 0x3e, 0x19, 0x24, 0x7d, 0x92, 0x9c, 0x6d, 0x08, + 0xff, 0x8e, 0xf2, 0x33, 0x48, 0x08, 0xdb, 0x8d, 0xae, 0xf0, 0xb9, 0x91, 0x06, 0xd3, 0xfd, 0xf8, + 0x3d, 0x1d, 0x76, 0xf7, 0xd2, 0x20, 0x3f, 0x81, 0x89, 0xd7, 0x06, 0xc9, 0x4b, 0xe3, 0xd2, 0xd1, + 0x9c, 0x2d, 0x46, 0xe5, 0xef, 0x82, 0xcf, 0xe0, 0x68, 0x65, 0xc9, 0x47, 0x78, 0x1c, 0xe1, 0x9f, + 0xf9, 0xe6, 0x03, 0xf8, 0x63, 0xf4, 0x78, 0xe8, 0x3c, 0xee, 0x7a, 0x0d, 0x8e, 0x30, 0xee, 0x8e, + 0xe3, 0x57, 0x62, 0x87, 0xb0, 0xd8, 0xb2, 0x9d, 0x5d, 0xff, 0x33, 0xdd, 0x1b, 0x67, 0x7b, 0x4b, + 0x05, 0xe7, 0x95, 0x35, 0xbb, 0xa8, 0x65, 0x32, 0x9c, 0x55, 0x74, 0x1d, 0x14, 0xec, 0xe9, 0xb2, + 0xd6, 0x7e, 0x15, 0x94, 0xa8, 0xac, 0xc9, 0x3b, 0x36, 0xdf, 0x82, 0xf2, 0x01, 0xca, 0x63, 0x61, + 0x4e, 0xa9, 0x83, 0xf8, 0xb8, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x91, 0x32, 0x51, 0xa7, 0xca, + 0x01, 0x00, 0x00, }, } func init() { yarpc.RegisterClientBuilder( - func(clientConfig transport.ClientConfig, structField reflect.StructField) GatewayServiceYARPCClient { - return NewGatewayServiceYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) + func(clientConfig transport.ClientConfig, structField reflect.StructField) SubmitQueueGatewayYARPCClient { + return NewSubmitQueueGatewayYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) }, ) } diff --git a/gateway/protopb/gateway_grpc.pb.go b/gateway/protopb/gateway_grpc.pb.go index 615bc626..74293266 100644 --- a/gateway/protopb/gateway_grpc.pb.go +++ b/gateway/protopb/gateway_grpc.pb.go @@ -19,107 +19,107 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - GatewayService_Ping_FullMethodName = "/uber.devexp.submitqueue.gateway.GatewayService/Ping" + SubmitQueueGateway_Ping_FullMethodName = "/uber.devexp.submitqueue.gateway.SubmitQueueGateway/Ping" ) -// GatewayServiceClient is the client API for GatewayService service. +// SubmitQueueGatewayClient is the client API for SubmitQueueGateway service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // -// GatewayService provides the gateway API -type GatewayServiceClient interface { +// SubmitQueueGateway provides the gateway API +type SubmitQueueGatewayClient interface { // Ping returns a response indicating the service is alive Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) } -type gatewayServiceClient struct { +type submitQueueGatewayClient struct { cc grpc.ClientConnInterface } -func NewGatewayServiceClient(cc grpc.ClientConnInterface) GatewayServiceClient { - return &gatewayServiceClient{cc} +func NewSubmitQueueGatewayClient(cc grpc.ClientConnInterface) SubmitQueueGatewayClient { + return &submitQueueGatewayClient{cc} } -func (c *gatewayServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { +func (c *submitQueueGatewayClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingResponse) - err := c.cc.Invoke(ctx, GatewayService_Ping_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, SubmitQueueGateway_Ping_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -// GatewayServiceServer is the server API for GatewayService service. -// All implementations must embed UnimplementedGatewayServiceServer +// SubmitQueueGatewayServer is the server API for SubmitQueueGateway service. +// All implementations must embed UnimplementedSubmitQueueGatewayServer // for forward compatibility. // -// GatewayService provides the gateway API -type GatewayServiceServer interface { +// SubmitQueueGateway provides the gateway API +type SubmitQueueGatewayServer interface { // Ping returns a response indicating the service is alive Ping(context.Context, *PingRequest) (*PingResponse, error) - mustEmbedUnimplementedGatewayServiceServer() + mustEmbedUnimplementedSubmitQueueGatewayServer() } -// UnimplementedGatewayServiceServer must be embedded to have +// UnimplementedSubmitQueueGatewayServer must be embedded to have // forward compatible implementations. // // NOTE: this should be embedded by value instead of pointer to avoid a nil // pointer dereference when methods are called. -type UnimplementedGatewayServiceServer struct{} +type UnimplementedSubmitQueueGatewayServer struct{} -func (UnimplementedGatewayServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { +func (UnimplementedSubmitQueueGatewayServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } -func (UnimplementedGatewayServiceServer) mustEmbedUnimplementedGatewayServiceServer() {} -func (UnimplementedGatewayServiceServer) testEmbeddedByValue() {} +func (UnimplementedSubmitQueueGatewayServer) mustEmbedUnimplementedSubmitQueueGatewayServer() {} +func (UnimplementedSubmitQueueGatewayServer) testEmbeddedByValue() {} -// UnsafeGatewayServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to GatewayServiceServer will +// UnsafeSubmitQueueGatewayServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SubmitQueueGatewayServer will // result in compilation errors. -type UnsafeGatewayServiceServer interface { - mustEmbedUnimplementedGatewayServiceServer() +type UnsafeSubmitQueueGatewayServer interface { + mustEmbedUnimplementedSubmitQueueGatewayServer() } -func RegisterGatewayServiceServer(s grpc.ServiceRegistrar, srv GatewayServiceServer) { - // If the following call pancis, it indicates UnimplementedGatewayServiceServer was +func RegisterSubmitQueueGatewayServer(s grpc.ServiceRegistrar, srv SubmitQueueGatewayServer) { + // If the following call pancis, it indicates UnimplementedSubmitQueueGatewayServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { t.testEmbeddedByValue() } - s.RegisterService(&GatewayService_ServiceDesc, srv) + s.RegisterService(&SubmitQueueGateway_ServiceDesc, srv) } -func _GatewayService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _SubmitQueueGateway_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PingRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(GatewayServiceServer).Ping(ctx, in) + return srv.(SubmitQueueGatewayServer).Ping(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: GatewayService_Ping_FullMethodName, + FullMethod: SubmitQueueGateway_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GatewayServiceServer).Ping(ctx, req.(*PingRequest)) + return srv.(SubmitQueueGatewayServer).Ping(ctx, req.(*PingRequest)) } return interceptor(ctx, in, info, handler) } -// GatewayService_ServiceDesc is the grpc.ServiceDesc for GatewayService service. +// SubmitQueueGateway_ServiceDesc is the grpc.ServiceDesc for SubmitQueueGateway service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var GatewayService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "uber.devexp.submitqueue.gateway.GatewayService", - HandlerType: (*GatewayServiceServer)(nil), +var SubmitQueueGateway_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "uber.devexp.submitqueue.gateway.SubmitQueueGateway", + HandlerType: (*SubmitQueueGatewayServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Ping", - Handler: _GatewayService_Ping_Handler, + Handler: _SubmitQueueGateway_Ping_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/go.mod b/go.mod index 7f18cccb..54e783f2 100644 --- a/go.mod +++ b/go.mod @@ -20,19 +20,20 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/prometheus/client_golang v1.4.1 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.9.1 // indirect - github.com/prometheus/procfs v0.0.9 // indirect + github.com/prometheus/common v0.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect github.com/twmb/murmur3 v1.1.8 // indirect github.com/uber-go/tally v3.5.8+incompatible // indirect + github.com/uber-go/tally/v4 v4.1.17 // indirect github.com/uber/tchannel-go v1.34.4 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/net/metrics v1.4.0 // indirect go.uber.org/thriftrw v1.32.0 // indirect - go.uber.org/zap v1.27.0 // indirect + go.uber.org/zap v1.27.1 // indirect golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.18.0 // indirect diff --git a/go.sum b/go.sum index 521d6870..d04f2bb9 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -5,6 +6,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -23,8 +25,10 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -41,25 +45,40 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3-0.20190920234318-1680a479a2cf/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -72,10 +91,12 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a h1:AA9vgIBDjMHPC2McaGPojgV2dcI78ZC0TLNhYCXEKH8= @@ -85,6 +106,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -95,16 +119,23 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.8.0/go.mod h1:PC/OgXc+UN7B4ALwvn1yzVZmVwvhXp5JsbBv6wSv6i0= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.9 h1:DksSrntiTPE63NQuxGcFa1OS/odKfwJu3PJHrhKAy7Q= github.com/prometheus/procfs v0.0.9/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/samuel/go-thrift v0.0.0-20191111193933-5165175b40af h1:EiWVfh8mr40yFZEui2oF0d45KgH48PkB2H0Z0GANvSI= github.com/samuel/go-thrift v0.0.0-20191111193933-5165175b40af/go.mod h1:Vrkh1pnjV9Bl8c3P9zH0/D4NlOHWP5d4/hF4YTULaec= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d h1:X4+kt6zM/OVO6gbJdAfJR60MGPsqCzbtXNnjoGqdfAs= github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -121,6 +152,8 @@ github.com/uber-go/mapdecode v1.0.0/go.mod h1:b5nP15FwXTgpjTjeA9A2uTHXV5UJCl4arw github.com/uber-go/tally v3.3.12+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= github.com/uber-go/tally v3.5.8+incompatible h1:Z2vK6ib6G/r6bAGu7lAI/98cLPLUOtdHrY2bBikk4wg= github.com/uber-go/tally v3.5.8+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= +github.com/uber-go/tally/v4 v4.1.17 h1:C+U4BKtVDXTszuzU+WH8JVQvRVnaVKxzZrROFyDrvS8= +github.com/uber-go/tally/v4 v4.1.17/go.mod h1:ZdpiHRGSa3z4NIAc1VlEH4SiknR885fOIF08xmS0gaU= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= @@ -151,6 +184,8 @@ go.uber.org/yarpc v1.81.0 h1:Zn4a0EmcbSx59lHH7RcYQpM+NE4TZUNkJjP3ARBVonc= go.uber.org/yarpc v1.81.0/go.mod h1:TaNLpGJjNYVqubGunV4Quw9MlK8vMIR/nHrc9BZhmJ8= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -169,22 +204,27 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -194,16 +234,23 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200117145432-59e60aa80a0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -226,12 +273,20 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto/googleapis/rpc v0.0.0-20241230172942-26aa7a208def h1:4P81qv5JXI/sDNae2ClVx88cgDDA6DPilADkG9tYKz8= google.golang.org/genproto/googleapis/rpc v0.0.0-20241230172942-26aa7a208def/go.mod h1:bdAgzvd4kFrpykc5/AC2eLUiegK9T/qxZHD4hXYf/ho= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -243,6 +298,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/integration_tests/BUILD.bazel b/integration_tests/BUILD.bazel new file mode 100644 index 00000000..a27b7525 --- /dev/null +++ b/integration_tests/BUILD.bazel @@ -0,0 +1,20 @@ +load("@rules_go//go:def.bzl", "go_test") + +go_test( + name = "e2e_test", + srcs = ["ping_test.go"], + # End-to-end tests require all servers to be running + # They validate the entire system working together + tags = [ + "e2e", + "integration", + "manual", + ], + deps = [ + "//gateway/protopb", + "//orchestrator/protopb", + "//speculator/protopb", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], +) diff --git a/integration_tests/README.md b/integration_tests/README.md new file mode 100644 index 00000000..4d716f92 --- /dev/null +++ b/integration_tests/README.md @@ -0,0 +1,169 @@ +# End-to-End Tests + +This directory contains end-to-end (e2e) tests for the SubmitQueue system. These tests validate that all services work together correctly as a complete system. + +**Note:** For testing individual services in isolation, see the integration tests in each service's directory: +- `gateway/integration_tests/` - Gateway service tests +- `orchestrator/integration_tests/` - Orchestrator service tests +- `speculator/integration_tests/` - Speculator service tests + +## Running Tests + +### Prerequisites + +All servers must be running before executing the tests. Start them in separate terminals or in the background: + +```bash +# Build everything first +make build + +# Start all servers +./bin/gateway_server & +./bin/orchestrator_server & +./bin/speculator_server & +``` + +### Using Make (Recommended) + +```bash +# Run end-to-end tests (all servers must be running) +make e2e-test + +# Run integration tests for individual services +make integration-test-gateway # Just Gateway +make integration-test-orchestrator # Just Orchestrator +make integration-test-speculator # Just Speculator +make integration-test # All services + +``` + +### Using Bazel directly + +```bash +# Run end-to-end tests +./tools/bazel test //integration_tests:e2e_test --test_output=all + +# Run individual service integration tests +./tools/bazel test //gateway:integration_test --test_output=all +./tools/bazel test //orchestrator:integration_test --test_output=all +./tools/bazel test //speculator:integration_test --test_output=all + +# Run all service integration tests +./tools/bazel test //gateway:integration_test //orchestrator:integration_test //speculator:integration_test --test_output=all + +# The tests are tagged as 'manual' so they won't run with 'bazel test //...' +# This is intentional since they require servers to be running +``` + +## Test Structure + +### End-to-End Tests (this directory) + +- `TestEndToEndAllServices` - Validates all services are running and responding correctly + +### Service Integration Tests (in each service directory) + +- `gateway/integration_tests/` - Tests Gateway service in isolation +- `orchestrator/integration_tests/` - Tests Orchestrator service in isolation +- `speculator/integration_tests/` - Tests Speculator service in isolation + +## Adding New Tests + +### 1. Add a test for a new API endpoint in an existing service + +Add the test to the service's `integration_tests/` folder (e.g., create `gateway/integration_tests/submit_test.go`): + +```go +func TestNewMethod(t *testing.T) { + addr := getEnvOrDefault("GATEWAY_ADDR", "localhost:8081") + + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Gateway server not ready: %v", err) + } + defer conn.Close() + + client := pb.NewSubmitQueueGatewayClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + req := &pb.NewMethodRequest{ + Field: "value", + } + + resp, err := client.NewMethod(ctx, req) + if err != nil { + t.Fatalf("NewMethod failed: %v", err) + } + + // Add your assertions here +} +``` + +### 2. Add integration tests for a new service + +1. Create `newservice/integration_tests/` folder +2. Add test files like `newservice/integration_tests/ping_test.go` +3. Add `go_test` rule to `newservice/BUILD.bazel`: +```python +go_test( + name = "integration_test", + srcs = ["integration_tests/ping_test.go"], + deps = [ + "//newservice/protopb", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], + tags = ["manual", "integration"], +) +``` +4. Update Makefile to add `integration-test-newservice` target +5. Update CI workflow to start the new service and run its tests + +### 3. Add end-to-end tests + +For system-wide tests that involve multiple services, add them to `integration_tests/api_test.go`. + +## Environment Variables + +Tests support the following environment variables to customize server addresses: + +- `GATEWAY_ADDR` - Gateway server address (default: `localhost:8081`) +- `ORCHESTRATOR_ADDR` - Orchestrator server address (default: `localhost:8082`) +- `SPECULATOR_ADDR` - Speculator server address (default: `localhost:8083`) + +Example with Bazel: +```bash +GATEWAY_ADDR=10.0.0.1:8081 ./tools/bazel test //integration_tests:integration_tests --test_output=all +``` + +Example with Go: +```bash +GATEWAY_ADDR=10.0.0.1:8081 go test ./integration_tests -v +``` + +## CI Usage + +In GitHub Actions CI, the workflow: +1. Builds all services +2. Starts all servers in the background +3. Runs integration tests +4. Stops servers + +See `.github/workflows/build_and_test.yml` for the full workflow. + +## Troubleshooting + +**Tests fail with "connection refused":** +- Ensure all servers are running +- Check that servers are listening on the expected ports: `lsof -i :8081` +- Verify servers are healthy using the clients: `./bin/gateway_client -message test` + +**Tests timeout:** +- Servers may be slow to start +- Increase `serverReadyTimeout` in the test code +- Check server logs for startup errors + +**Import errors:** +- Run `go mod tidy` to ensure all dependencies are downloaded +- Regenerate proto files if needed: `make proto` diff --git a/integration_tests/ping_test.go b/integration_tests/ping_test.go new file mode 100644 index 00000000..7d4d4577 --- /dev/null +++ b/integration_tests/ping_test.go @@ -0,0 +1,133 @@ +package integration_tests + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + gatewaypb "github.com/uber/submitqueue/gateway/protopb" + orchestratorpb "github.com/uber/submitqueue/orchestrator/protopb" + speculatorpb "github.com/uber/submitqueue/speculator/protopb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + defaultTimeout = 5 * time.Second + serverReadyTimeout = 30 * time.Second + retryInterval = 500 * time.Millisecond +) + +// TestPingForAllServices tests that all services are running and responding +// This is an end-to-end test that validates the entire system is running +func TestPingForAllServices(t *testing.T) { + // Test Gateway + t.Run("Gateway", func(t *testing.T) { + addr := getEnvOrDefault("GATEWAY_ADDR", "localhost:8081") + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Gateway server not ready: %v", err) + } + defer conn.Close() + + client := gatewaypb.NewSubmitQueueGatewayClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + resp, err := client.Ping(ctx, &gatewaypb.PingRequest{Message: "e2e test"}) + if err != nil { + t.Fatalf("Gateway Ping failed: %v", err) + } + if resp.ServiceName != "gateway" { + t.Errorf("Expected service name 'gateway', got '%s'", resp.ServiceName) + } + t.Logf("Gateway is healthy: %s", resp.Message) + }) + + // Test Orchestrator + t.Run("Orchestrator", func(t *testing.T) { + addr := getEnvOrDefault("ORCHESTRATOR_ADDR", "localhost:8082") + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Orchestrator server not ready: %v", err) + } + defer conn.Close() + + client := orchestratorpb.NewSubmitQueueOrchestratorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + resp, err := client.Ping(ctx, &orchestratorpb.PingRequest{Message: "e2e test"}) + if err != nil { + t.Fatalf("Orchestrator Ping failed: %v", err) + } + if resp.ServiceName != "orchestrator" { + t.Errorf("Expected service name 'orchestrator', got '%s'", resp.ServiceName) + } + t.Logf("Orchestrator is healthy: %s", resp.Message) + }) + + // Test Speculator + t.Run("Speculator", func(t *testing.T) { + addr := getEnvOrDefault("SPECULATOR_ADDR", "localhost:8083") + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Speculator server not ready: %v", err) + } + defer conn.Close() + + client := speculatorpb.NewSubmitQueueSpeculatorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + resp, err := client.Ping(ctx, &speculatorpb.PingRequest{Message: "e2e test"}) + if err != nil { + t.Fatalf("Speculator Ping failed: %v", err) + } + if resp.ServiceName != "speculator" { + t.Errorf("Expected service name 'speculator', got '%s'", resp.ServiceName) + } + t.Logf("Speculator is healthy: %s", resp.Message) + }) + + t.Log("All services are healthy and responding correctly") +} + +// waitForServer waits for a gRPC server to become ready +func waitForServer(t *testing.T, addr string, timeout time.Duration) (*grpc.ClientConn, error) { + t.Helper() + + deadline := time.Now().Add(timeout) + var lastErr error + + for time.Now().Before(deadline) { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + conn, err := grpc.DialContext( + ctx, + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + cancel() + + if err == nil { + t.Logf("Server at %s is ready", addr) + return conn, nil + } + + lastErr = err + time.Sleep(retryInterval) + } + + return nil, fmt.Errorf("server at %s not ready after %v: %w", addr, timeout, lastErr) +} + +// getEnvOrDefault returns the value of an environment variable or a default value +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/orchestrator/BUILD.bazel b/orchestrator/BUILD.bazel deleted file mode 100644 index 7dd59c45..00000000 --- a/orchestrator/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@rules_go//go:def.bzl", "go_library") - -go_library( - name = "orchestrator", - srcs = [], - importpath = "github.com/uber/submitqueue/orchestrator", - visibility = ["//visibility:public"], - deps = [ - "//orchestrator/core/controller", - "//orchestrator/protopb", - ], -) diff --git a/orchestrator/core/controller/BUILD.bazel b/orchestrator/core/controller/BUILD.bazel index 841f6754..30cffc5e 100644 --- a/orchestrator/core/controller/BUILD.bazel +++ b/orchestrator/core/controller/BUILD.bazel @@ -1,9 +1,24 @@ -load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "controller", srcs = ["ping.go"], importpath = "github.com/uber/submitqueue/orchestrator/core/controller", visibility = ["//visibility:public"], - deps = ["//orchestrator/protopb"], + deps = [ + "//orchestrator/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "controller_test", + srcs = ["ping_test.go"], + embed = [":controller"], + deps = [ + "//orchestrator/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], ) diff --git a/orchestrator/core/controller/ping.go b/orchestrator/core/controller/ping.go index 3c97b8d5..52ba1a97 100644 --- a/orchestrator/core/controller/ping.go +++ b/orchestrator/core/controller/ping.go @@ -5,28 +5,57 @@ import ( "os" "time" + "github.com/uber-go/tally/v4" pb "github.com/uber/submitqueue/orchestrator/protopb" + "go.uber.org/zap" ) -// PingServiceImpl implements the OrchestratorService gRPC service for the orchestrator -type PingServiceImpl struct { - pb.UnimplementedOrchestratorServiceServer +// PingController handles ping business logic for the orchestrator +type PingController struct { + logger *zap.Logger + metricsScope tally.Scope } -// NewPingService creates a new instance of the orchestrator ping service -func NewPingService() *PingServiceImpl { - return &PingServiceImpl{} +// NewPingController creates a new instance of the orchestrator ping controller +func NewPingController(logger *zap.Logger, scope tally.Scope) *PingController { + if logger == nil { + logger = zap.NewNop() + } + if scope == nil { + scope = tally.NoopScope + } + + return &PingController{ + logger: logger, + metricsScope: scope, + } } // Ping handles the ping request and returns a response -func (s *PingServiceImpl) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { +func (c *PingController) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + start := time.Now() + defer func() { + c.metricsScope.Timer("ping_latency").Record(time.Since(start)) + }() + + c.metricsScope.Counter("ping_requests_total").Inc(1) + message := "pong" + isEcho := false if req.Message != "" { message = "echo: " + req.Message + isEcho = true + c.metricsScope.Counter("echo_requests_total").Inc(1) } hostname, _ := os.Hostname() + c.logger.Info("ping request received", + zap.String("message", req.Message), + zap.Bool("is_echo", isEcho), + zap.String("hostname", hostname), + ) + return &pb.PingResponse{ Message: message, ServiceName: "orchestrator", diff --git a/orchestrator/core/controller/ping_test.go b/orchestrator/core/controller/ping_test.go new file mode 100644 index 00000000..381dad05 --- /dev/null +++ b/orchestrator/core/controller/ping_test.go @@ -0,0 +1,114 @@ +package controller + +import ( + "context" + "testing" + "time" + + pb "github.com/uber/submitqueue/orchestrator/protopb" +) + +func TestNewPingController(t *testing.T) { + controller := NewPingController(nil, nil) + if controller == nil { + t.Fatal("NewPingController() returned nil") + } +} + +func TestPing_DefaultMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != "pong" { + t.Errorf("Expected message 'pong', got '%s'", resp.Message) + } +} + +func TestPing_CustomMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + testCases := []struct { + name string + input string + expected string + }{ + {"simple message", "hello", "echo: hello"}, + {"message with spaces", "hello world", "echo: hello world"}, + {"special characters", "test!@#", "echo: test!@#"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + req := &pb.PingRequest{Message: tc.input} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != tc.expected { + t.Errorf("Expected message '%s', got '%s'", tc.expected, resp.Message) + } + }) + } +} + +func TestPing_ServiceName(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.ServiceName != "orchestrator" { + t.Errorf("Expected service name 'orchestrator', got '%s'", resp.ServiceName) + } +} + +func TestPing_Timestamp(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + before := time.Now().Unix() + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + after := time.Now().Unix() + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Timestamp < before || resp.Timestamp > after { + t.Errorf("Timestamp %d is not within expected range [%d, %d]", resp.Timestamp, before, after) + } +} + +func TestPing_Hostname(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + // Hostname should be set (non-empty string) + // We don't check the exact value as it depends on the environment + if resp.Hostname == "" { + t.Error("Expected hostname to be set, got empty string") + } +} diff --git a/orchestrator/integration_tests/BUILD.bazel b/orchestrator/integration_tests/BUILD.bazel new file mode 100644 index 00000000..72eb8910 --- /dev/null +++ b/orchestrator/integration_tests/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_test") + +go_test( + name = "integration_test", + srcs = ["ping_test.go"], + tags = [ + "integration", + "manual", + ], + deps = [ + "//orchestrator/protopb", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], +) diff --git a/orchestrator/integration_tests/ping_test.go b/orchestrator/integration_tests/ping_test.go new file mode 100644 index 00000000..91bd5e82 --- /dev/null +++ b/orchestrator/integration_tests/ping_test.go @@ -0,0 +1,102 @@ +package orchestrator_test + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + pb "github.com/uber/submitqueue/orchestrator/protopb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + defaultTimeout = 5 * time.Second + serverReadyTimeout = 30 * time.Second + retryInterval = 500 * time.Millisecond +) + +// TestPingAPI tests the Orchestrator service Ping API +func TestPingAPI(t *testing.T) { + addr := getEnvOrDefault("ORCHESTRATOR_ADDR", "localhost:8082") + + // Wait for server to be ready + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Orchestrator server not ready: %v", err) + } + defer conn.Close() + + client := pb.NewSubmitQueueOrchestratorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + // Test Ping API + req := &pb.PingRequest{ + Message: "integration test", + } + + resp, err := client.Ping(ctx, req) + if err != nil { + t.Fatalf("Ping failed: %v", err) + } + + // Validate response + if resp.Message == "" { + t.Error("Response message is empty") + } + if resp.ServiceName != "orchestrator" { + t.Errorf("Expected service name 'orchestrator', got '%s'", resp.ServiceName) + } + if resp.Timestamp == 0 { + t.Error("Timestamp is zero") + } + if resp.Hostname == "" { + t.Error("Hostname is empty") + } + + t.Logf("Orchestrator Ping test passed:") + t.Logf(" Message: %s", resp.Message) + t.Logf(" Service: %s", resp.ServiceName) + t.Logf(" Timestamp: %d", resp.Timestamp) + t.Logf(" Hostname: %s", resp.Hostname) +} + +// waitForServer waits for a gRPC server to become ready +func waitForServer(t *testing.T, addr string, timeout time.Duration) (*grpc.ClientConn, error) { + t.Helper() + + deadline := time.Now().Add(timeout) + var lastErr error + + for time.Now().Before(deadline) { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + conn, err := grpc.DialContext( + ctx, + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + cancel() + + if err == nil { + t.Logf("Server at %s is ready", addr) + return conn, nil + } + + lastErr = err + time.Sleep(retryInterval) + } + + return nil, fmt.Errorf("server at %s not ready after %v: %w", addr, timeout, lastErr) +} + +// getEnvOrDefault returns the value of an environment variable or a default value +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/orchestrator/proto/BUILD.bazel b/orchestrator/proto/BUILD.bazel index 30db6ea9..cdbe7a08 100644 --- a/orchestrator/proto/BUILD.bazel +++ b/orchestrator/proto/BUILD.bazel @@ -26,3 +26,10 @@ go_library( importpath = "github.com/uber/submitqueue/orchestrator/proto", visibility = ["//visibility:public"], ) + +go_library( + name = "protopb", + embed = [":orchestratorpb_go_proto"], + importpath = "github.com/uber/submitqueue/orchestrator/protopb", + visibility = ["//visibility:public"], +) diff --git a/orchestrator/proto/orchestrator.proto b/orchestrator/proto/orchestrator.proto index f7d5ff08..a0e9bfa5 100644 --- a/orchestrator/proto/orchestrator.proto +++ b/orchestrator/proto/orchestrator.proto @@ -25,8 +25,8 @@ message PingResponse { string hostname = 4; } -// OrchestratorService provides the orchestrator API -service OrchestratorService { +// SubmitQueueOrchestrator provides the orchestrator API +service SubmitQueueOrchestrator { // Ping returns a response indicating the service is alive rpc Ping(PingRequest) returns (PingResponse) {} } diff --git a/orchestrator/protopb/BUILD.bazel b/orchestrator/protopb/BUILD.bazel index e91f7ed5..0f40d168 100644 --- a/orchestrator/protopb/BUILD.bazel +++ b/orchestrator/protopb/BUILD.bazel @@ -4,8 +4,8 @@ go_library( name = "protopb", srcs = [ "orchestrator.pb.go", - "orchestrator_grpc.pb.go", "orchestrator.pb.yarpc.go", + "orchestrator_grpc.pb.go", ], importpath = "github.com/uber/submitqueue/orchestrator/protopb", visibility = ["//visibility:public"], diff --git a/orchestrator/protopb/orchestrator.pb.go b/orchestrator/protopb/orchestrator.pb.go index 817ece21..8d95c07c 100644 --- a/orchestrator/protopb/orchestrator.pb.go +++ b/orchestrator/protopb/orchestrator.pb.go @@ -151,8 +151,8 @@ const file_orchestrator_proto_rawDesc = "" + "\amessage\x18\x01 \x01(\tR\amessage\x12!\n" + "\fservice_name\x18\x02 \x01(\tR\vserviceName\x12\x1c\n" + "\ttimestamp\x18\x03 \x01(\x03R\ttimestamp\x12\x1a\n" + - "\bhostname\x18\x04 \x01(\tR\bhostname2\x86\x01\n" + - "\x13OrchestratorService\x12o\n" + + "\bhostname\x18\x04 \x01(\tR\bhostname2\x8a\x01\n" + + "\x17SubmitQueueOrchestrator\x12o\n" + "\x04Ping\x121.uber.devexp.submitqueue.orchestrator.PingRequest\x1a2.uber.devexp.submitqueue.orchestrator.PingResponse\"\x00Bq\n" + "(com.uber.devexp.submitqueue.orchestratorB\x11OrchestratorProtoP\x01Z0github.com/uber/submitqueue/orchestrator/protopbb\x06proto3" @@ -174,8 +174,8 @@ var file_orchestrator_proto_goTypes = []any{ (*PingResponse)(nil), // 1: uber.devexp.submitqueue.orchestrator.PingResponse } var file_orchestrator_proto_depIdxs = []int32{ - 0, // 0: uber.devexp.submitqueue.orchestrator.OrchestratorService.Ping:input_type -> uber.devexp.submitqueue.orchestrator.PingRequest - 1, // 1: uber.devexp.submitqueue.orchestrator.OrchestratorService.Ping:output_type -> uber.devexp.submitqueue.orchestrator.PingResponse + 0, // 0: uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator.Ping:input_type -> uber.devexp.submitqueue.orchestrator.PingRequest + 1, // 1: uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator.Ping:output_type -> uber.devexp.submitqueue.orchestrator.PingResponse 1, // [1:2] is the sub-list for method output_type 0, // [0:1] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name diff --git a/orchestrator/protopb/orchestrator.pb.yarpc.go b/orchestrator/protopb/orchestrator.pb.yarpc.go index a7fde298..41ba19d5 100644 --- a/orchestrator/protopb/orchestrator.pb.yarpc.go +++ b/orchestrator/protopb/orchestrator.pb.yarpc.go @@ -20,15 +20,15 @@ import ( var _ = ioutil.NopCloser -// OrchestratorServiceYARPCClient is the YARPC client-side interface for the OrchestratorService service. -type OrchestratorServiceYARPCClient interface { +// SubmitQueueOrchestratorYARPCClient is the YARPC client-side interface for the SubmitQueueOrchestrator service. +type SubmitQueueOrchestratorYARPCClient interface { Ping(context.Context, *PingRequest, ...yarpc.CallOption) (*PingResponse, error) } -func newOrchestratorServiceYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) OrchestratorServiceYARPCClient { - return &_OrchestratorServiceYARPCCaller{protobuf.NewStreamClient( +func newSubmitQueueOrchestratorYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) SubmitQueueOrchestratorYARPCClient { + return &_SubmitQueueOrchestratorYARPCCaller{protobuf.NewStreamClient( protobuf.ClientParams{ - ServiceName: "uber.devexp.submitqueue.orchestrator.OrchestratorService", + ServiceName: "uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator", ClientConfig: clientConfig, AnyResolver: anyResolver, Options: options, @@ -36,33 +36,33 @@ func newOrchestratorServiceYARPCClient(clientConfig transport.ClientConfig, anyR )} } -// NewOrchestratorServiceYARPCClient builds a new YARPC client for the OrchestratorService service. -func NewOrchestratorServiceYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) OrchestratorServiceYARPCClient { - return newOrchestratorServiceYARPCClient(clientConfig, nil, options...) +// NewSubmitQueueOrchestratorYARPCClient builds a new YARPC client for the SubmitQueueOrchestrator service. +func NewSubmitQueueOrchestratorYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) SubmitQueueOrchestratorYARPCClient { + return newSubmitQueueOrchestratorYARPCClient(clientConfig, nil, options...) } -// OrchestratorServiceYARPCServer is the YARPC server-side interface for the OrchestratorService service. -type OrchestratorServiceYARPCServer interface { +// SubmitQueueOrchestratorYARPCServer is the YARPC server-side interface for the SubmitQueueOrchestrator service. +type SubmitQueueOrchestratorYARPCServer interface { Ping(context.Context, *PingRequest) (*PingResponse, error) } -type buildOrchestratorServiceYARPCProceduresParams struct { - Server OrchestratorServiceYARPCServer +type buildSubmitQueueOrchestratorYARPCProceduresParams struct { + Server SubmitQueueOrchestratorYARPCServer AnyResolver jsonpb.AnyResolver } -func buildOrchestratorServiceYARPCProcedures(params buildOrchestratorServiceYARPCProceduresParams) []transport.Procedure { - handler := &_OrchestratorServiceYARPCHandler{params.Server} +func buildSubmitQueueOrchestratorYARPCProcedures(params buildSubmitQueueOrchestratorYARPCProceduresParams) []transport.Procedure { + handler := &_SubmitQueueOrchestratorYARPCHandler{params.Server} return protobuf.BuildProcedures( protobuf.BuildProceduresParams{ - ServiceName: "uber.devexp.submitqueue.orchestrator.OrchestratorService", + ServiceName: "uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator", UnaryHandlerParams: []protobuf.BuildProceduresUnaryHandlerParams{ { MethodName: "Ping", Handler: protobuf.NewUnaryHandler( protobuf.UnaryHandlerParams{ Handle: handler.Ping, - NewRequest: newOrchestratorServiceServicePingYARPCRequest, + NewRequest: newSubmitQueueOrchestratorServicePingYARPCRequest, AnyResolver: params.AnyResolver, }, ), @@ -74,16 +74,16 @@ func buildOrchestratorServiceYARPCProcedures(params buildOrchestratorServiceYARP ) } -// BuildOrchestratorServiceYARPCProcedures prepares an implementation of the OrchestratorService service for YARPC registration. -func BuildOrchestratorServiceYARPCProcedures(server OrchestratorServiceYARPCServer) []transport.Procedure { - return buildOrchestratorServiceYARPCProcedures(buildOrchestratorServiceYARPCProceduresParams{Server: server}) +// BuildSubmitQueueOrchestratorYARPCProcedures prepares an implementation of the SubmitQueueOrchestrator service for YARPC registration. +func BuildSubmitQueueOrchestratorYARPCProcedures(server SubmitQueueOrchestratorYARPCServer) []transport.Procedure { + return buildSubmitQueueOrchestratorYARPCProcedures(buildSubmitQueueOrchestratorYARPCProceduresParams{Server: server}) } -// FxOrchestratorServiceYARPCClientParams defines the input -// for NewFxOrchestratorServiceYARPCClient. It provides the -// paramaters to get a OrchestratorServiceYARPCClient in an +// FxSubmitQueueOrchestratorYARPCClientParams defines the input +// for NewFxSubmitQueueOrchestratorYARPCClient. It provides the +// paramaters to get a SubmitQueueOrchestratorYARPCClient in an // Fx application. -type FxOrchestratorServiceYARPCClientParams struct { +type FxSubmitQueueOrchestratorYARPCClientParams struct { fx.In Provider yarpc.ClientConfig @@ -91,28 +91,28 @@ type FxOrchestratorServiceYARPCClientParams struct { Restriction restriction.Checker `optional:"true"` } -// FxOrchestratorServiceYARPCClientResult defines the output -// of NewFxOrchestratorServiceYARPCClient. It provides a -// OrchestratorServiceYARPCClient to an Fx application. -type FxOrchestratorServiceYARPCClientResult struct { +// FxSubmitQueueOrchestratorYARPCClientResult defines the output +// of NewFxSubmitQueueOrchestratorYARPCClient. It provides a +// SubmitQueueOrchestratorYARPCClient to an Fx application. +type FxSubmitQueueOrchestratorYARPCClientResult struct { fx.Out - Client OrchestratorServiceYARPCClient + Client SubmitQueueOrchestratorYARPCClient // We are using an fx.Out struct here instead of just returning a client // so that we can add more values or add named versions of the client in // the future without breaking any existing code. } -// NewFxOrchestratorServiceYARPCClient provides a OrchestratorServiceYARPCClient +// NewFxSubmitQueueOrchestratorYARPCClient provides a SubmitQueueOrchestratorYARPCClient // to an Fx application using the given name for routing. // // fx.Provide( -// protopb.NewFxOrchestratorServiceYARPCClient("service-name"), +// protopb.NewFxSubmitQueueOrchestratorYARPCClient("service-name"), // ... // ) -func NewFxOrchestratorServiceYARPCClient(name string, options ...protobuf.ClientOption) interface{} { - return func(params FxOrchestratorServiceYARPCClientParams) FxOrchestratorServiceYARPCClientResult { +func NewFxSubmitQueueOrchestratorYARPCClient(name string, options ...protobuf.ClientOption) interface{} { + return func(params FxSubmitQueueOrchestratorYARPCClientParams) FxSubmitQueueOrchestratorYARPCClientResult { cc := params.Provider.ClientConfig(name) if params.Restriction != nil { @@ -123,91 +123,91 @@ func NewFxOrchestratorServiceYARPCClient(name string, options ...protobuf.Client } } - return FxOrchestratorServiceYARPCClientResult{ - Client: newOrchestratorServiceYARPCClient(cc, params.AnyResolver, options...), + return FxSubmitQueueOrchestratorYARPCClientResult{ + Client: newSubmitQueueOrchestratorYARPCClient(cc, params.AnyResolver, options...), } } } -// FxOrchestratorServiceYARPCProceduresParams defines the input -// for NewFxOrchestratorServiceYARPCProcedures. It provides the -// paramaters to get OrchestratorServiceYARPCServer procedures in an +// FxSubmitQueueOrchestratorYARPCProceduresParams defines the input +// for NewFxSubmitQueueOrchestratorYARPCProcedures. It provides the +// paramaters to get SubmitQueueOrchestratorYARPCServer procedures in an // Fx application. -type FxOrchestratorServiceYARPCProceduresParams struct { +type FxSubmitQueueOrchestratorYARPCProceduresParams struct { fx.In - Server OrchestratorServiceYARPCServer + Server SubmitQueueOrchestratorYARPCServer AnyResolver jsonpb.AnyResolver `name:"yarpcfx" optional:"true"` } -// FxOrchestratorServiceYARPCProceduresResult defines the output -// of NewFxOrchestratorServiceYARPCProcedures. It provides -// OrchestratorServiceYARPCServer procedures to an Fx application. +// FxSubmitQueueOrchestratorYARPCProceduresResult defines the output +// of NewFxSubmitQueueOrchestratorYARPCProcedures. It provides +// SubmitQueueOrchestratorYARPCServer procedures to an Fx application. // // The procedures are provided to the "yarpcfx" value group. // Dig 1.2 or newer must be used for this feature to work. -type FxOrchestratorServiceYARPCProceduresResult struct { +type FxSubmitQueueOrchestratorYARPCProceduresResult struct { fx.Out Procedures []transport.Procedure `group:"yarpcfx"` ReflectionMeta reflection.ServerMeta `group:"yarpcfx"` } -// NewFxOrchestratorServiceYARPCProcedures provides OrchestratorServiceYARPCServer procedures to an Fx application. -// It expects a OrchestratorServiceYARPCServer to be present in the container. +// NewFxSubmitQueueOrchestratorYARPCProcedures provides SubmitQueueOrchestratorYARPCServer procedures to an Fx application. +// It expects a SubmitQueueOrchestratorYARPCServer to be present in the container. // // fx.Provide( -// protopb.NewFxOrchestratorServiceYARPCProcedures(), +// protopb.NewFxSubmitQueueOrchestratorYARPCProcedures(), // ... // ) -func NewFxOrchestratorServiceYARPCProcedures() interface{} { - return func(params FxOrchestratorServiceYARPCProceduresParams) FxOrchestratorServiceYARPCProceduresResult { - return FxOrchestratorServiceYARPCProceduresResult{ - Procedures: buildOrchestratorServiceYARPCProcedures(buildOrchestratorServiceYARPCProceduresParams{ +func NewFxSubmitQueueOrchestratorYARPCProcedures() interface{} { + return func(params FxSubmitQueueOrchestratorYARPCProceduresParams) FxSubmitQueueOrchestratorYARPCProceduresResult { + return FxSubmitQueueOrchestratorYARPCProceduresResult{ + Procedures: buildSubmitQueueOrchestratorYARPCProcedures(buildSubmitQueueOrchestratorYARPCProceduresParams{ Server: params.Server, AnyResolver: params.AnyResolver, }), - ReflectionMeta: OrchestratorServiceReflectionMeta, + ReflectionMeta: SubmitQueueOrchestratorReflectionMeta, } } } -// OrchestratorServiceReflectionMeta is the reflection server metadata +// SubmitQueueOrchestratorReflectionMeta is the reflection server metadata // required for using the gRPC reflection protocol with YARPC. // // See https://github.com/grpc/grpc/blob/master/doc/server-reflection.md. -var OrchestratorServiceReflectionMeta = reflection.ServerMeta{ - ServiceName: "uber.devexp.submitqueue.orchestrator.OrchestratorService", +var SubmitQueueOrchestratorReflectionMeta = reflection.ServerMeta{ + ServiceName: "uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator", FileDescriptors: yarpcFileDescriptorClosure96b6e6782baaa298, } -type _OrchestratorServiceYARPCCaller struct { +type _SubmitQueueOrchestratorYARPCCaller struct { streamClient protobuf.StreamClient } -func (c *_OrchestratorServiceYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { - responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newOrchestratorServiceServicePingYARPCResponse, options...) +func (c *_SubmitQueueOrchestratorYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { + responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newSubmitQueueOrchestratorServicePingYARPCResponse, options...) if responseMessage == nil { return nil, err } response, ok := responseMessage.(*PingResponse) if !ok { - return nil, protobuf.CastError(emptyOrchestratorServiceServicePingYARPCResponse, responseMessage) + return nil, protobuf.CastError(emptySubmitQueueOrchestratorServicePingYARPCResponse, responseMessage) } return response, err } -type _OrchestratorServiceYARPCHandler struct { - server OrchestratorServiceYARPCServer +type _SubmitQueueOrchestratorYARPCHandler struct { + server SubmitQueueOrchestratorYARPCServer } -func (h *_OrchestratorServiceYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { +func (h *_SubmitQueueOrchestratorYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { var request *PingRequest var ok bool if requestMessage != nil { request, ok = requestMessage.(*PingRequest) if !ok { - return nil, protobuf.CastError(emptyOrchestratorServiceServicePingYARPCRequest, requestMessage) + return nil, protobuf.CastError(emptySubmitQueueOrchestratorServicePingYARPCRequest, requestMessage) } } response, err := h.server.Ping(ctx, request) @@ -217,46 +217,46 @@ func (h *_OrchestratorServiceYARPCHandler) Ping(ctx context.Context, requestMess return response, err } -func newOrchestratorServiceServicePingYARPCRequest() proto.Message { +func newSubmitQueueOrchestratorServicePingYARPCRequest() proto.Message { return &PingRequest{} } -func newOrchestratorServiceServicePingYARPCResponse() proto.Message { +func newSubmitQueueOrchestratorServicePingYARPCResponse() proto.Message { return &PingResponse{} } var ( - emptyOrchestratorServiceServicePingYARPCRequest = &PingRequest{} - emptyOrchestratorServiceServicePingYARPCResponse = &PingResponse{} + emptySubmitQueueOrchestratorServicePingYARPCRequest = &PingRequest{} + emptySubmitQueueOrchestratorServicePingYARPCResponse = &PingResponse{} ) var yarpcFileDescriptorClosure96b6e6782baaa298 = [][]byte{ // orchestrator.proto []byte{ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xbf, 0x4e, 0xc3, 0x30, - 0x10, 0x87, 0x31, 0xad, 0x80, 0x5e, 0xbb, 0x60, 0x96, 0xa8, 0x62, 0x28, 0x11, 0x12, 0x99, 0x1c, - 0x28, 0x6f, 0xd0, 0x07, 0x80, 0x28, 0x6c, 0x2c, 0x28, 0x09, 0xa7, 0xc4, 0x83, 0x63, 0xc7, 0x67, - 0x57, 0xbc, 0x00, 0x3c, 0x37, 0x8a, 0xc3, 0x1f, 0x2f, 0x48, 0x65, 0xf3, 0x9d, 0x7f, 0xdf, 0xe9, - 0x3e, 0x1d, 0x70, 0x6d, 0x9b, 0x0e, 0xc9, 0xd9, 0xca, 0x69, 0x2b, 0x8c, 0xd5, 0x4e, 0xf3, 0x6b, - 0x5f, 0xa3, 0x15, 0xaf, 0xb8, 0xc7, 0x37, 0x23, 0xc8, 0xd7, 0x4a, 0xba, 0xc1, 0xa3, 0x47, 0x11, - 0x67, 0xd3, 0x1b, 0x58, 0x16, 0xb2, 0x6f, 0x4b, 0x1c, 0x3c, 0x92, 0xe3, 0x09, 0x9c, 0x2a, 0x24, - 0xaa, 0x5a, 0x4c, 0xd8, 0x86, 0x65, 0x8b, 0xf2, 0xbb, 0x4c, 0xdf, 0x19, 0xac, 0xa6, 0x24, 0x19, - 0xdd, 0x13, 0xfe, 0x1d, 0xe5, 0x57, 0xb0, 0x22, 0xb4, 0x7b, 0xd9, 0xe0, 0x4b, 0x5f, 0x29, 0x4c, - 0x8e, 0xc3, 0xf7, 0xf2, 0xab, 0xf7, 0x50, 0x29, 0xe4, 0x97, 0xb0, 0x70, 0x52, 0x21, 0xb9, 0x4a, - 0x99, 0x64, 0xb6, 0x61, 0xd9, 0xac, 0xfc, 0x6d, 0xf0, 0x35, 0x9c, 0x75, 0x9a, 0x5c, 0x80, 0xe7, - 0x01, 0xfe, 0xa9, 0xb7, 0x1f, 0x0c, 0x2e, 0x1e, 0x23, 0x83, 0xa7, 0x69, 0x2a, 0xd7, 0x30, 0x1f, - 0xd7, 0xe3, 0x77, 0xe2, 0x10, 0x6f, 0x11, 0x49, 0xaf, 0xb7, 0xff, 0x41, 0x26, 0xfb, 0xf4, 0x68, - 0x37, 0x40, 0xd6, 0x68, 0x75, 0x10, 0xba, 0x3b, 0x8f, 0x37, 0x2e, 0xc6, 0xf3, 0x14, 0xec, 0xf9, - 0xb6, 0x95, 0xae, 0xf3, 0xb5, 0x68, 0xb4, 0xca, 0xc7, 0x29, 0x79, 0x84, 0xe7, 0x31, 0x9e, 0x87, - 0x83, 0x9a, 0xba, 0x3e, 0x09, 0x8f, 0xfb, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0xfb, 0x38, - 0x99, 0xef, 0x01, 0x00, 0x00, + 0x10, 0x87, 0x31, 0xad, 0x80, 0x5e, 0xbb, 0xe0, 0x85, 0xa8, 0x62, 0x28, 0x11, 0x12, 0x99, 0x1c, + 0x28, 0x6f, 0xd0, 0x07, 0x80, 0x10, 0x36, 0x16, 0x94, 0x84, 0x53, 0xe2, 0xc1, 0xb1, 0xe3, 0xb3, + 0x2b, 0x5e, 0x80, 0x85, 0xa7, 0x46, 0x71, 0xf9, 0xe3, 0x05, 0xa9, 0xdd, 0x7c, 0xe7, 0xdf, 0x67, + 0xdd, 0xe7, 0x03, 0xae, 0x6d, 0xd3, 0x21, 0x39, 0x5b, 0x39, 0x6d, 0x85, 0xb1, 0xda, 0x69, 0x7e, + 0xed, 0x6b, 0xb4, 0xe2, 0x0d, 0xb7, 0xf8, 0x6e, 0x04, 0xf9, 0x5a, 0x49, 0x37, 0x78, 0xf4, 0x28, + 0xe2, 0x6c, 0x7a, 0x03, 0xf3, 0x42, 0xf6, 0x6d, 0x89, 0x83, 0x47, 0x72, 0x3c, 0x81, 0x53, 0x85, + 0x44, 0x55, 0x8b, 0x09, 0x5b, 0xb1, 0x6c, 0x56, 0xfe, 0x94, 0xe9, 0x07, 0x83, 0xc5, 0x2e, 0x49, + 0x46, 0xf7, 0x84, 0xff, 0x47, 0xf9, 0x15, 0x2c, 0x08, 0xed, 0x56, 0x36, 0xf8, 0xda, 0x57, 0x0a, + 0x93, 0xe3, 0x70, 0x3d, 0xff, 0xee, 0x3d, 0x54, 0x0a, 0xf9, 0x25, 0xcc, 0x9c, 0x54, 0x48, 0xae, + 0x52, 0x26, 0x99, 0xac, 0x58, 0x36, 0x29, 0xff, 0x1a, 0x7c, 0x09, 0x67, 0x9d, 0x26, 0x17, 0xe0, + 0x69, 0x80, 0x7f, 0xeb, 0xf5, 0x27, 0x83, 0x8b, 0xe7, 0x60, 0xf3, 0x34, 0xda, 0x3c, 0x46, 0x32, + 0x5c, 0xc3, 0x74, 0x1c, 0x91, 0xdf, 0x89, 0x7d, 0xdc, 0x45, 0x24, 0xbe, 0x5c, 0x1f, 0x82, 0xec, + 0x7e, 0x20, 0x3d, 0xda, 0x0c, 0x90, 0x35, 0x5a, 0xed, 0x85, 0x6e, 0xce, 0xe3, 0x51, 0x8b, 0x71, + 0x45, 0x05, 0x7b, 0xb9, 0x6d, 0xa5, 0xeb, 0x7c, 0x2d, 0x1a, 0xad, 0xf2, 0xf1, 0x95, 0x3c, 0xc2, + 0xf3, 0x18, 0xcf, 0xc3, 0x52, 0x4d, 0x5d, 0x9f, 0x84, 0xc3, 0xfd, 0x57, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x72, 0x59, 0xe2, 0x9d, 0xf3, 0x01, 0x00, 0x00, }, } func init() { yarpc.RegisterClientBuilder( - func(clientConfig transport.ClientConfig, structField reflect.StructField) OrchestratorServiceYARPCClient { - return NewOrchestratorServiceYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) + func(clientConfig transport.ClientConfig, structField reflect.StructField) SubmitQueueOrchestratorYARPCClient { + return NewSubmitQueueOrchestratorYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) }, ) } diff --git a/orchestrator/protopb/orchestrator_grpc.pb.go b/orchestrator/protopb/orchestrator_grpc.pb.go index 2477987a..af424e1e 100644 --- a/orchestrator/protopb/orchestrator_grpc.pb.go +++ b/orchestrator/protopb/orchestrator_grpc.pb.go @@ -19,107 +19,108 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - OrchestratorService_Ping_FullMethodName = "/uber.devexp.submitqueue.orchestrator.OrchestratorService/Ping" + SubmitQueueOrchestrator_Ping_FullMethodName = "/uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator/Ping" ) -// OrchestratorServiceClient is the client API for OrchestratorService service. +// SubmitQueueOrchestratorClient is the client API for SubmitQueueOrchestrator service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // -// OrchestratorService provides the orchestrator API -type OrchestratorServiceClient interface { +// SubmitQueueOrchestrator provides the orchestrator API +type SubmitQueueOrchestratorClient interface { // Ping returns a response indicating the service is alive Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) } -type orchestratorServiceClient struct { +type submitQueueOrchestratorClient struct { cc grpc.ClientConnInterface } -func NewOrchestratorServiceClient(cc grpc.ClientConnInterface) OrchestratorServiceClient { - return &orchestratorServiceClient{cc} +func NewSubmitQueueOrchestratorClient(cc grpc.ClientConnInterface) SubmitQueueOrchestratorClient { + return &submitQueueOrchestratorClient{cc} } -func (c *orchestratorServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { +func (c *submitQueueOrchestratorClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingResponse) - err := c.cc.Invoke(ctx, OrchestratorService_Ping_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, SubmitQueueOrchestrator_Ping_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -// OrchestratorServiceServer is the server API for OrchestratorService service. -// All implementations must embed UnimplementedOrchestratorServiceServer +// SubmitQueueOrchestratorServer is the server API for SubmitQueueOrchestrator service. +// All implementations must embed UnimplementedSubmitQueueOrchestratorServer // for forward compatibility. // -// OrchestratorService provides the orchestrator API -type OrchestratorServiceServer interface { +// SubmitQueueOrchestrator provides the orchestrator API +type SubmitQueueOrchestratorServer interface { // Ping returns a response indicating the service is alive Ping(context.Context, *PingRequest) (*PingResponse, error) - mustEmbedUnimplementedOrchestratorServiceServer() + mustEmbedUnimplementedSubmitQueueOrchestratorServer() } -// UnimplementedOrchestratorServiceServer must be embedded to have +// UnimplementedSubmitQueueOrchestratorServer must be embedded to have // forward compatible implementations. // // NOTE: this should be embedded by value instead of pointer to avoid a nil // pointer dereference when methods are called. -type UnimplementedOrchestratorServiceServer struct{} +type UnimplementedSubmitQueueOrchestratorServer struct{} -func (UnimplementedOrchestratorServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { +func (UnimplementedSubmitQueueOrchestratorServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } -func (UnimplementedOrchestratorServiceServer) mustEmbedUnimplementedOrchestratorServiceServer() {} -func (UnimplementedOrchestratorServiceServer) testEmbeddedByValue() {} +func (UnimplementedSubmitQueueOrchestratorServer) mustEmbedUnimplementedSubmitQueueOrchestratorServer() { +} +func (UnimplementedSubmitQueueOrchestratorServer) testEmbeddedByValue() {} -// UnsafeOrchestratorServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to OrchestratorServiceServer will +// UnsafeSubmitQueueOrchestratorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SubmitQueueOrchestratorServer will // result in compilation errors. -type UnsafeOrchestratorServiceServer interface { - mustEmbedUnimplementedOrchestratorServiceServer() +type UnsafeSubmitQueueOrchestratorServer interface { + mustEmbedUnimplementedSubmitQueueOrchestratorServer() } -func RegisterOrchestratorServiceServer(s grpc.ServiceRegistrar, srv OrchestratorServiceServer) { - // If the following call pancis, it indicates UnimplementedOrchestratorServiceServer was +func RegisterSubmitQueueOrchestratorServer(s grpc.ServiceRegistrar, srv SubmitQueueOrchestratorServer) { + // If the following call pancis, it indicates UnimplementedSubmitQueueOrchestratorServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { t.testEmbeddedByValue() } - s.RegisterService(&OrchestratorService_ServiceDesc, srv) + s.RegisterService(&SubmitQueueOrchestrator_ServiceDesc, srv) } -func _OrchestratorService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _SubmitQueueOrchestrator_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PingRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(OrchestratorServiceServer).Ping(ctx, in) + return srv.(SubmitQueueOrchestratorServer).Ping(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: OrchestratorService_Ping_FullMethodName, + FullMethod: SubmitQueueOrchestrator_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(OrchestratorServiceServer).Ping(ctx, req.(*PingRequest)) + return srv.(SubmitQueueOrchestratorServer).Ping(ctx, req.(*PingRequest)) } return interceptor(ctx, in, info, handler) } -// OrchestratorService_ServiceDesc is the grpc.ServiceDesc for OrchestratorService service. +// SubmitQueueOrchestrator_ServiceDesc is the grpc.ServiceDesc for SubmitQueueOrchestrator service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var OrchestratorService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "uber.devexp.submitqueue.orchestrator.OrchestratorService", - HandlerType: (*OrchestratorServiceServer)(nil), +var SubmitQueueOrchestrator_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "uber.devexp.submitqueue.orchestrator.SubmitQueueOrchestrator", + HandlerType: (*SubmitQueueOrchestratorServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Ping", - Handler: _OrchestratorService_Ping_Handler, + Handler: _SubmitQueueOrchestrator_Ping_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/speculator/BUILD.bazel b/speculator/BUILD.bazel deleted file mode 100644 index b4c7bc61..00000000 --- a/speculator/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@rules_go//go:def.bzl", "go_library") - -go_library( - name = "speculator", - srcs = [], - importpath = "github.com/uber/submitqueue/speculator", - visibility = ["//visibility:public"], - deps = [ - "//speculator/core/controller", - "//speculator/protopb", - ], -) diff --git a/speculator/core/controller/BUILD.bazel b/speculator/core/controller/BUILD.bazel index 3b295b32..b4692f8e 100644 --- a/speculator/core/controller/BUILD.bazel +++ b/speculator/core/controller/BUILD.bazel @@ -1,9 +1,24 @@ -load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "controller", srcs = ["ping.go"], importpath = "github.com/uber/submitqueue/speculator/core/controller", visibility = ["//visibility:public"], - deps = ["//speculator/protopb"], + deps = [ + "//speculator/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "controller_test", + srcs = ["ping_test.go"], + embed = [":controller"], + deps = [ + "//speculator/protopb", + "@com_github_uber_go_tally_v4//:tally", + "@org_uber_go_zap//:zap", + ], ) diff --git a/speculator/core/controller/ping.go b/speculator/core/controller/ping.go index d7b68279..a636643b 100644 --- a/speculator/core/controller/ping.go +++ b/speculator/core/controller/ping.go @@ -5,28 +5,57 @@ import ( "os" "time" + "github.com/uber-go/tally/v4" pb "github.com/uber/submitqueue/speculator/protopb" + "go.uber.org/zap" ) -// PingServiceImpl implements the SpeculatorService gRPC service for the speculator -type PingServiceImpl struct { - pb.UnimplementedSpeculatorServiceServer +// PingController handles ping business logic for the speculator +type PingController struct { + logger *zap.Logger + metricsScope tally.Scope } -// NewPingService creates a new instance of the speculator ping service -func NewPingService() *PingServiceImpl { - return &PingServiceImpl{} +// NewPingController creates a new instance of the speculator ping controller +func NewPingController(logger *zap.Logger, scope tally.Scope) *PingController { + if logger == nil { + logger = zap.NewNop() + } + if scope == nil { + scope = tally.NoopScope + } + + return &PingController{ + logger: logger, + metricsScope: scope, + } } // Ping handles the ping request and returns a response -func (s *PingServiceImpl) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { +func (c *PingController) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) { + start := time.Now() + defer func() { + c.metricsScope.Timer("ping_latency").Record(time.Since(start)) + }() + + c.metricsScope.Counter("ping_requests_total").Inc(1) + message := "pong" + isEcho := false if req.Message != "" { message = "echo: " + req.Message + isEcho = true + c.metricsScope.Counter("echo_requests_total").Inc(1) } hostname, _ := os.Hostname() + c.logger.Info("ping request received", + zap.String("message", req.Message), + zap.Bool("is_echo", isEcho), + zap.String("hostname", hostname), + ) + return &pb.PingResponse{ Message: message, ServiceName: "speculator", diff --git a/speculator/core/controller/ping_test.go b/speculator/core/controller/ping_test.go new file mode 100644 index 00000000..b0f60f06 --- /dev/null +++ b/speculator/core/controller/ping_test.go @@ -0,0 +1,114 @@ +package controller + +import ( + "context" + "testing" + "time" + + pb "github.com/uber/submitqueue/speculator/protopb" +) + +func TestNewPingController(t *testing.T) { + controller := NewPingController(nil, nil) + if controller == nil { + t.Fatal("NewPingController() returned nil") + } +} + +func TestPing_DefaultMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != "pong" { + t.Errorf("Expected message 'pong', got '%s'", resp.Message) + } +} + +func TestPing_CustomMessage(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + testCases := []struct { + name string + input string + expected string + }{ + {"simple message", "hello", "echo: hello"}, + {"message with spaces", "hello world", "echo: hello world"}, + {"special characters", "test!@#", "echo: test!@#"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + req := &pb.PingRequest{Message: tc.input} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Message != tc.expected { + t.Errorf("Expected message '%s', got '%s'", tc.expected, resp.Message) + } + }) + } +} + +func TestPing_ServiceName(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.ServiceName != "speculator" { + t.Errorf("Expected service name 'speculator', got '%s'", resp.ServiceName) + } +} + +func TestPing_Timestamp(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + before := time.Now().Unix() + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + after := time.Now().Unix() + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + if resp.Timestamp < before || resp.Timestamp > after { + t.Errorf("Timestamp %d is not within expected range [%d, %d]", resp.Timestamp, before, after) + } +} + +func TestPing_Hostname(t *testing.T) { + controller := NewPingController(nil, nil) + ctx := context.Background() + + req := &pb.PingRequest{} + resp, err := controller.Ping(ctx, req) + + if err != nil { + t.Fatalf("Ping() returned error: %v", err) + } + + // Hostname should be set (non-empty string) + // We don't check the exact value as it depends on the environment + if resp.Hostname == "" { + t.Error("Expected hostname to be set, got empty string") + } +} diff --git a/speculator/integration_tests/BUILD.bazel b/speculator/integration_tests/BUILD.bazel new file mode 100644 index 00000000..5a188d51 --- /dev/null +++ b/speculator/integration_tests/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_test") + +go_test( + name = "integration_test", + srcs = ["ping_test.go"], + tags = [ + "integration", + "manual", + ], + deps = [ + "//speculator/protopb", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], +) diff --git a/speculator/integration_tests/ping_test.go b/speculator/integration_tests/ping_test.go new file mode 100644 index 00000000..00e0fa44 --- /dev/null +++ b/speculator/integration_tests/ping_test.go @@ -0,0 +1,102 @@ +package speculator_test + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + pb "github.com/uber/submitqueue/speculator/protopb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + defaultTimeout = 5 * time.Second + serverReadyTimeout = 30 * time.Second + retryInterval = 500 * time.Millisecond +) + +// TestPingAPI tests the Speculator service Ping API +func TestPingAPI(t *testing.T) { + addr := getEnvOrDefault("SPECULATOR_ADDR", "localhost:8083") + + // Wait for server to be ready + conn, err := waitForServer(t, addr, serverReadyTimeout) + if err != nil { + t.Fatalf("Speculator server not ready: %v", err) + } + defer conn.Close() + + client := pb.NewSubmitQueueSpeculatorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + // Test Ping API + req := &pb.PingRequest{ + Message: "integration test", + } + + resp, err := client.Ping(ctx, req) + if err != nil { + t.Fatalf("Ping failed: %v", err) + } + + // Validate response + if resp.Message == "" { + t.Error("Response message is empty") + } + if resp.ServiceName != "speculator" { + t.Errorf("Expected service name 'speculator', got '%s'", resp.ServiceName) + } + if resp.Timestamp == 0 { + t.Error("Timestamp is zero") + } + if resp.Hostname == "" { + t.Error("Hostname is empty") + } + + t.Logf("Speculator Ping test passed:") + t.Logf(" Message: %s", resp.Message) + t.Logf(" Service: %s", resp.ServiceName) + t.Logf(" Timestamp: %d", resp.Timestamp) + t.Logf(" Hostname: %s", resp.Hostname) +} + +// waitForServer waits for a gRPC server to become ready +func waitForServer(t *testing.T, addr string, timeout time.Duration) (*grpc.ClientConn, error) { + t.Helper() + + deadline := time.Now().Add(timeout) + var lastErr error + + for time.Now().Before(deadline) { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + conn, err := grpc.DialContext( + ctx, + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + cancel() + + if err == nil { + t.Logf("Server at %s is ready", addr) + return conn, nil + } + + lastErr = err + time.Sleep(retryInterval) + } + + return nil, fmt.Errorf("server at %s not ready after %v: %w", addr, timeout, lastErr) +} + +// getEnvOrDefault returns the value of an environment variable or a default value +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/speculator/proto/BUILD.bazel b/speculator/proto/BUILD.bazel index cdd7abbb..65de9c86 100644 --- a/speculator/proto/BUILD.bazel +++ b/speculator/proto/BUILD.bazel @@ -26,3 +26,10 @@ go_library( importpath = "github.com/uber/submitqueue/speculator/proto", visibility = ["//visibility:public"], ) + +go_library( + name = "protopb", + embed = [":speculatorpb_go_proto"], + importpath = "github.com/uber/submitqueue/speculator/protopb", + visibility = ["//visibility:public"], +) diff --git a/speculator/proto/speculator.proto b/speculator/proto/speculator.proto index 40d75630..1746aa3c 100644 --- a/speculator/proto/speculator.proto +++ b/speculator/proto/speculator.proto @@ -25,8 +25,8 @@ message PingResponse { string hostname = 4; } -// SpeculatorService provides the speculator API -service SpeculatorService { +// SubmitQueueSpeculator provides the speculator API +service SubmitQueueSpeculator { // Ping returns a response indicating the service is alive rpc Ping(PingRequest) returns (PingResponse) {} } diff --git a/speculator/protopb/BUILD.bazel b/speculator/protopb/BUILD.bazel index 837f5ed1..f4bfd2b1 100644 --- a/speculator/protopb/BUILD.bazel +++ b/speculator/protopb/BUILD.bazel @@ -4,8 +4,8 @@ go_library( name = "protopb", srcs = [ "speculator.pb.go", - "speculator_grpc.pb.go", "speculator.pb.yarpc.go", + "speculator_grpc.pb.go", ], importpath = "github.com/uber/submitqueue/speculator/protopb", visibility = ["//visibility:public"], diff --git a/speculator/protopb/speculator.pb.go b/speculator/protopb/speculator.pb.go index 43e518ba..6be0c329 100644 --- a/speculator/protopb/speculator.pb.go +++ b/speculator/protopb/speculator.pb.go @@ -151,8 +151,8 @@ const file_speculator_proto_rawDesc = "" + "\amessage\x18\x01 \x01(\tR\amessage\x12!\n" + "\fservice_name\x18\x02 \x01(\tR\vserviceName\x12\x1c\n" + "\ttimestamp\x18\x03 \x01(\x03R\ttimestamp\x12\x1a\n" + - "\bhostname\x18\x04 \x01(\tR\bhostname2\x80\x01\n" + - "\x11SpeculatorService\x12k\n" + + "\bhostname\x18\x04 \x01(\tR\bhostname2\x84\x01\n" + + "\x15SubmitQueueSpeculator\x12k\n" + "\x04Ping\x12/.uber.devexp.submitqueue.speculator.PingRequest\x1a0.uber.devexp.submitqueue.speculator.PingResponse\"\x00Bk\n" + "&com.uber.devexp.submitqueue.speculatorB\x0fSpeculatorProtoP\x01Z.github.com/uber/submitqueue/speculator/protopbb\x06proto3" @@ -174,8 +174,8 @@ var file_speculator_proto_goTypes = []any{ (*PingResponse)(nil), // 1: uber.devexp.submitqueue.speculator.PingResponse } var file_speculator_proto_depIdxs = []int32{ - 0, // 0: uber.devexp.submitqueue.speculator.SpeculatorService.Ping:input_type -> uber.devexp.submitqueue.speculator.PingRequest - 1, // 1: uber.devexp.submitqueue.speculator.SpeculatorService.Ping:output_type -> uber.devexp.submitqueue.speculator.PingResponse + 0, // 0: uber.devexp.submitqueue.speculator.SubmitQueueSpeculator.Ping:input_type -> uber.devexp.submitqueue.speculator.PingRequest + 1, // 1: uber.devexp.submitqueue.speculator.SubmitQueueSpeculator.Ping:output_type -> uber.devexp.submitqueue.speculator.PingResponse 1, // [1:2] is the sub-list for method output_type 0, // [0:1] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name diff --git a/speculator/protopb/speculator.pb.yarpc.go b/speculator/protopb/speculator.pb.yarpc.go index 6a3e7026..2c273555 100644 --- a/speculator/protopb/speculator.pb.yarpc.go +++ b/speculator/protopb/speculator.pb.yarpc.go @@ -20,15 +20,15 @@ import ( var _ = ioutil.NopCloser -// SpeculatorServiceYARPCClient is the YARPC client-side interface for the SpeculatorService service. -type SpeculatorServiceYARPCClient interface { +// SubmitQueueSpeculatorYARPCClient is the YARPC client-side interface for the SubmitQueueSpeculator service. +type SubmitQueueSpeculatorYARPCClient interface { Ping(context.Context, *PingRequest, ...yarpc.CallOption) (*PingResponse, error) } -func newSpeculatorServiceYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) SpeculatorServiceYARPCClient { - return &_SpeculatorServiceYARPCCaller{protobuf.NewStreamClient( +func newSubmitQueueSpeculatorYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) SubmitQueueSpeculatorYARPCClient { + return &_SubmitQueueSpeculatorYARPCCaller{protobuf.NewStreamClient( protobuf.ClientParams{ - ServiceName: "uber.devexp.submitqueue.speculator.SpeculatorService", + ServiceName: "uber.devexp.submitqueue.speculator.SubmitQueueSpeculator", ClientConfig: clientConfig, AnyResolver: anyResolver, Options: options, @@ -36,33 +36,33 @@ func newSpeculatorServiceYARPCClient(clientConfig transport.ClientConfig, anyRes )} } -// NewSpeculatorServiceYARPCClient builds a new YARPC client for the SpeculatorService service. -func NewSpeculatorServiceYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) SpeculatorServiceYARPCClient { - return newSpeculatorServiceYARPCClient(clientConfig, nil, options...) +// NewSubmitQueueSpeculatorYARPCClient builds a new YARPC client for the SubmitQueueSpeculator service. +func NewSubmitQueueSpeculatorYARPCClient(clientConfig transport.ClientConfig, options ...protobuf.ClientOption) SubmitQueueSpeculatorYARPCClient { + return newSubmitQueueSpeculatorYARPCClient(clientConfig, nil, options...) } -// SpeculatorServiceYARPCServer is the YARPC server-side interface for the SpeculatorService service. -type SpeculatorServiceYARPCServer interface { +// SubmitQueueSpeculatorYARPCServer is the YARPC server-side interface for the SubmitQueueSpeculator service. +type SubmitQueueSpeculatorYARPCServer interface { Ping(context.Context, *PingRequest) (*PingResponse, error) } -type buildSpeculatorServiceYARPCProceduresParams struct { - Server SpeculatorServiceYARPCServer +type buildSubmitQueueSpeculatorYARPCProceduresParams struct { + Server SubmitQueueSpeculatorYARPCServer AnyResolver jsonpb.AnyResolver } -func buildSpeculatorServiceYARPCProcedures(params buildSpeculatorServiceYARPCProceduresParams) []transport.Procedure { - handler := &_SpeculatorServiceYARPCHandler{params.Server} +func buildSubmitQueueSpeculatorYARPCProcedures(params buildSubmitQueueSpeculatorYARPCProceduresParams) []transport.Procedure { + handler := &_SubmitQueueSpeculatorYARPCHandler{params.Server} return protobuf.BuildProcedures( protobuf.BuildProceduresParams{ - ServiceName: "uber.devexp.submitqueue.speculator.SpeculatorService", + ServiceName: "uber.devexp.submitqueue.speculator.SubmitQueueSpeculator", UnaryHandlerParams: []protobuf.BuildProceduresUnaryHandlerParams{ { MethodName: "Ping", Handler: protobuf.NewUnaryHandler( protobuf.UnaryHandlerParams{ Handle: handler.Ping, - NewRequest: newSpeculatorServiceServicePingYARPCRequest, + NewRequest: newSubmitQueueSpeculatorServicePingYARPCRequest, AnyResolver: params.AnyResolver, }, ), @@ -74,16 +74,16 @@ func buildSpeculatorServiceYARPCProcedures(params buildSpeculatorServiceYARPCPro ) } -// BuildSpeculatorServiceYARPCProcedures prepares an implementation of the SpeculatorService service for YARPC registration. -func BuildSpeculatorServiceYARPCProcedures(server SpeculatorServiceYARPCServer) []transport.Procedure { - return buildSpeculatorServiceYARPCProcedures(buildSpeculatorServiceYARPCProceduresParams{Server: server}) +// BuildSubmitQueueSpeculatorYARPCProcedures prepares an implementation of the SubmitQueueSpeculator service for YARPC registration. +func BuildSubmitQueueSpeculatorYARPCProcedures(server SubmitQueueSpeculatorYARPCServer) []transport.Procedure { + return buildSubmitQueueSpeculatorYARPCProcedures(buildSubmitQueueSpeculatorYARPCProceduresParams{Server: server}) } -// FxSpeculatorServiceYARPCClientParams defines the input -// for NewFxSpeculatorServiceYARPCClient. It provides the -// paramaters to get a SpeculatorServiceYARPCClient in an +// FxSubmitQueueSpeculatorYARPCClientParams defines the input +// for NewFxSubmitQueueSpeculatorYARPCClient. It provides the +// paramaters to get a SubmitQueueSpeculatorYARPCClient in an // Fx application. -type FxSpeculatorServiceYARPCClientParams struct { +type FxSubmitQueueSpeculatorYARPCClientParams struct { fx.In Provider yarpc.ClientConfig @@ -91,28 +91,28 @@ type FxSpeculatorServiceYARPCClientParams struct { Restriction restriction.Checker `optional:"true"` } -// FxSpeculatorServiceYARPCClientResult defines the output -// of NewFxSpeculatorServiceYARPCClient. It provides a -// SpeculatorServiceYARPCClient to an Fx application. -type FxSpeculatorServiceYARPCClientResult struct { +// FxSubmitQueueSpeculatorYARPCClientResult defines the output +// of NewFxSubmitQueueSpeculatorYARPCClient. It provides a +// SubmitQueueSpeculatorYARPCClient to an Fx application. +type FxSubmitQueueSpeculatorYARPCClientResult struct { fx.Out - Client SpeculatorServiceYARPCClient + Client SubmitQueueSpeculatorYARPCClient // We are using an fx.Out struct here instead of just returning a client // so that we can add more values or add named versions of the client in // the future without breaking any existing code. } -// NewFxSpeculatorServiceYARPCClient provides a SpeculatorServiceYARPCClient +// NewFxSubmitQueueSpeculatorYARPCClient provides a SubmitQueueSpeculatorYARPCClient // to an Fx application using the given name for routing. // // fx.Provide( -// protopb.NewFxSpeculatorServiceYARPCClient("service-name"), +// protopb.NewFxSubmitQueueSpeculatorYARPCClient("service-name"), // ... // ) -func NewFxSpeculatorServiceYARPCClient(name string, options ...protobuf.ClientOption) interface{} { - return func(params FxSpeculatorServiceYARPCClientParams) FxSpeculatorServiceYARPCClientResult { +func NewFxSubmitQueueSpeculatorYARPCClient(name string, options ...protobuf.ClientOption) interface{} { + return func(params FxSubmitQueueSpeculatorYARPCClientParams) FxSubmitQueueSpeculatorYARPCClientResult { cc := params.Provider.ClientConfig(name) if params.Restriction != nil { @@ -123,91 +123,91 @@ func NewFxSpeculatorServiceYARPCClient(name string, options ...protobuf.ClientOp } } - return FxSpeculatorServiceYARPCClientResult{ - Client: newSpeculatorServiceYARPCClient(cc, params.AnyResolver, options...), + return FxSubmitQueueSpeculatorYARPCClientResult{ + Client: newSubmitQueueSpeculatorYARPCClient(cc, params.AnyResolver, options...), } } } -// FxSpeculatorServiceYARPCProceduresParams defines the input -// for NewFxSpeculatorServiceYARPCProcedures. It provides the -// paramaters to get SpeculatorServiceYARPCServer procedures in an +// FxSubmitQueueSpeculatorYARPCProceduresParams defines the input +// for NewFxSubmitQueueSpeculatorYARPCProcedures. It provides the +// paramaters to get SubmitQueueSpeculatorYARPCServer procedures in an // Fx application. -type FxSpeculatorServiceYARPCProceduresParams struct { +type FxSubmitQueueSpeculatorYARPCProceduresParams struct { fx.In - Server SpeculatorServiceYARPCServer + Server SubmitQueueSpeculatorYARPCServer AnyResolver jsonpb.AnyResolver `name:"yarpcfx" optional:"true"` } -// FxSpeculatorServiceYARPCProceduresResult defines the output -// of NewFxSpeculatorServiceYARPCProcedures. It provides -// SpeculatorServiceYARPCServer procedures to an Fx application. +// FxSubmitQueueSpeculatorYARPCProceduresResult defines the output +// of NewFxSubmitQueueSpeculatorYARPCProcedures. It provides +// SubmitQueueSpeculatorYARPCServer procedures to an Fx application. // // The procedures are provided to the "yarpcfx" value group. // Dig 1.2 or newer must be used for this feature to work. -type FxSpeculatorServiceYARPCProceduresResult struct { +type FxSubmitQueueSpeculatorYARPCProceduresResult struct { fx.Out Procedures []transport.Procedure `group:"yarpcfx"` ReflectionMeta reflection.ServerMeta `group:"yarpcfx"` } -// NewFxSpeculatorServiceYARPCProcedures provides SpeculatorServiceYARPCServer procedures to an Fx application. -// It expects a SpeculatorServiceYARPCServer to be present in the container. +// NewFxSubmitQueueSpeculatorYARPCProcedures provides SubmitQueueSpeculatorYARPCServer procedures to an Fx application. +// It expects a SubmitQueueSpeculatorYARPCServer to be present in the container. // // fx.Provide( -// protopb.NewFxSpeculatorServiceYARPCProcedures(), +// protopb.NewFxSubmitQueueSpeculatorYARPCProcedures(), // ... // ) -func NewFxSpeculatorServiceYARPCProcedures() interface{} { - return func(params FxSpeculatorServiceYARPCProceduresParams) FxSpeculatorServiceYARPCProceduresResult { - return FxSpeculatorServiceYARPCProceduresResult{ - Procedures: buildSpeculatorServiceYARPCProcedures(buildSpeculatorServiceYARPCProceduresParams{ +func NewFxSubmitQueueSpeculatorYARPCProcedures() interface{} { + return func(params FxSubmitQueueSpeculatorYARPCProceduresParams) FxSubmitQueueSpeculatorYARPCProceduresResult { + return FxSubmitQueueSpeculatorYARPCProceduresResult{ + Procedures: buildSubmitQueueSpeculatorYARPCProcedures(buildSubmitQueueSpeculatorYARPCProceduresParams{ Server: params.Server, AnyResolver: params.AnyResolver, }), - ReflectionMeta: SpeculatorServiceReflectionMeta, + ReflectionMeta: SubmitQueueSpeculatorReflectionMeta, } } } -// SpeculatorServiceReflectionMeta is the reflection server metadata +// SubmitQueueSpeculatorReflectionMeta is the reflection server metadata // required for using the gRPC reflection protocol with YARPC. // // See https://github.com/grpc/grpc/blob/master/doc/server-reflection.md. -var SpeculatorServiceReflectionMeta = reflection.ServerMeta{ - ServiceName: "uber.devexp.submitqueue.speculator.SpeculatorService", +var SubmitQueueSpeculatorReflectionMeta = reflection.ServerMeta{ + ServiceName: "uber.devexp.submitqueue.speculator.SubmitQueueSpeculator", FileDescriptors: yarpcFileDescriptorClosure4a6246af296c2143, } -type _SpeculatorServiceYARPCCaller struct { +type _SubmitQueueSpeculatorYARPCCaller struct { streamClient protobuf.StreamClient } -func (c *_SpeculatorServiceYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { - responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newSpeculatorServiceServicePingYARPCResponse, options...) +func (c *_SubmitQueueSpeculatorYARPCCaller) Ping(ctx context.Context, request *PingRequest, options ...yarpc.CallOption) (*PingResponse, error) { + responseMessage, err := c.streamClient.Call(ctx, "Ping", request, newSubmitQueueSpeculatorServicePingYARPCResponse, options...) if responseMessage == nil { return nil, err } response, ok := responseMessage.(*PingResponse) if !ok { - return nil, protobuf.CastError(emptySpeculatorServiceServicePingYARPCResponse, responseMessage) + return nil, protobuf.CastError(emptySubmitQueueSpeculatorServicePingYARPCResponse, responseMessage) } return response, err } -type _SpeculatorServiceYARPCHandler struct { - server SpeculatorServiceYARPCServer +type _SubmitQueueSpeculatorYARPCHandler struct { + server SubmitQueueSpeculatorYARPCServer } -func (h *_SpeculatorServiceYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { +func (h *_SubmitQueueSpeculatorYARPCHandler) Ping(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { var request *PingRequest var ok bool if requestMessage != nil { request, ok = requestMessage.(*PingRequest) if !ok { - return nil, protobuf.CastError(emptySpeculatorServiceServicePingYARPCRequest, requestMessage) + return nil, protobuf.CastError(emptySubmitQueueSpeculatorServicePingYARPCRequest, requestMessage) } } response, err := h.server.Ping(ctx, request) @@ -217,46 +217,46 @@ func (h *_SpeculatorServiceYARPCHandler) Ping(ctx context.Context, requestMessag return response, err } -func newSpeculatorServiceServicePingYARPCRequest() proto.Message { +func newSubmitQueueSpeculatorServicePingYARPCRequest() proto.Message { return &PingRequest{} } -func newSpeculatorServiceServicePingYARPCResponse() proto.Message { +func newSubmitQueueSpeculatorServicePingYARPCResponse() proto.Message { return &PingResponse{} } var ( - emptySpeculatorServiceServicePingYARPCRequest = &PingRequest{} - emptySpeculatorServiceServicePingYARPCResponse = &PingResponse{} + emptySubmitQueueSpeculatorServicePingYARPCRequest = &PingRequest{} + emptySubmitQueueSpeculatorServicePingYARPCResponse = &PingResponse{} ) var yarpcFileDescriptorClosure4a6246af296c2143 = [][]byte{ // speculator.proto []byte{ - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x31, 0x4f, 0xc3, 0x30, - 0x10, 0x85, 0x31, 0xad, 0x80, 0x5e, 0x2b, 0x01, 0x9e, 0xa2, 0x8a, 0xa1, 0x64, 0x80, 0x4e, 0x36, - 0x82, 0x7f, 0xd0, 0x1f, 0x80, 0xaa, 0x74, 0x63, 0x41, 0x76, 0x38, 0xa5, 0x56, 0x71, 0xec, 0xe6, - 0xec, 0x8a, 0x91, 0x85, 0xff, 0x8d, 0xe2, 0x40, 0xd3, 0x05, 0xd1, 0xcd, 0x77, 0x7e, 0xdf, 0xe9, - 0x3d, 0x3d, 0xb8, 0x22, 0x8f, 0x65, 0x7c, 0x57, 0xc1, 0x35, 0xc2, 0x37, 0x2e, 0x38, 0x9e, 0x47, - 0x8d, 0x8d, 0x78, 0xc3, 0x1d, 0x7e, 0x78, 0x41, 0x51, 0x5b, 0x13, 0xb6, 0x11, 0x23, 0x8a, 0x5e, - 0x99, 0xdf, 0xc3, 0x78, 0x69, 0xea, 0xaa, 0xc0, 0x6d, 0x44, 0x0a, 0x3c, 0x83, 0x73, 0x8b, 0x44, - 0xaa, 0xc2, 0x8c, 0xcd, 0xd8, 0x7c, 0x54, 0xfc, 0x8e, 0xf9, 0x17, 0x83, 0x49, 0xa7, 0x24, 0xef, - 0x6a, 0xc2, 0xbf, 0xa5, 0xfc, 0x16, 0x26, 0x84, 0xcd, 0xce, 0x94, 0xf8, 0x5a, 0x2b, 0x8b, 0xd9, - 0x69, 0xfa, 0x1e, 0xff, 0xec, 0x9e, 0x95, 0x45, 0x7e, 0x03, 0xa3, 0x60, 0x2c, 0x52, 0x50, 0xd6, - 0x67, 0x83, 0x19, 0x9b, 0x0f, 0x8a, 0x7e, 0xc1, 0xa7, 0x70, 0xb1, 0x76, 0x14, 0x12, 0x3c, 0x4c, - 0xf0, 0x7e, 0x7e, 0xfc, 0x64, 0x70, 0xbd, 0xda, 0xfb, 0x5f, 0x75, 0x37, 0xf9, 0x06, 0x86, 0xad, - 0x39, 0x2e, 0xc5, 0xff, 0x99, 0xc5, 0x41, 0xe0, 0xe9, 0xc3, 0xf1, 0x40, 0x97, 0x3b, 0x3f, 0x59, - 0x6c, 0xe0, 0xae, 0x74, 0xf6, 0x08, 0x70, 0x71, 0xd9, 0x3b, 0x5d, 0xb6, 0x95, 0x2c, 0xd9, 0x8b, - 0xa8, 0x4c, 0x58, 0x47, 0x2d, 0x4a, 0x67, 0x65, 0x7b, 0x41, 0x1e, 0xa0, 0xb2, 0x47, 0x65, 0xaa, - 0xd0, 0x6b, 0x7d, 0x96, 0x1e, 0x4f, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x3d, 0x19, 0x00, - 0xdf, 0x01, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xc1, 0x4a, 0x33, 0x31, + 0x10, 0xc7, 0xbf, 0x7c, 0x2d, 0x6a, 0xa7, 0x05, 0x25, 0x20, 0x2c, 0xc5, 0x43, 0xdd, 0x83, 0xf6, + 0x94, 0x88, 0xbe, 0x41, 0x1f, 0x40, 0xd6, 0xed, 0xcd, 0x8b, 0x24, 0xeb, 0xb0, 0x0d, 0x35, 0x9b, + 0x74, 0x27, 0x29, 0x3e, 0x80, 0xbe, 0xb7, 0x6c, 0xaa, 0xdd, 0x5e, 0xc4, 0xde, 0x32, 0x93, 0xff, + 0x6f, 0x98, 0x1f, 0x03, 0x17, 0xe4, 0xb1, 0x8a, 0x6f, 0x2a, 0xb8, 0x56, 0xf8, 0xd6, 0x05, 0xc7, + 0xf3, 0xa8, 0xb1, 0x15, 0xaf, 0xb8, 0xc5, 0x77, 0x2f, 0x28, 0x6a, 0x6b, 0xc2, 0x26, 0x62, 0x44, + 0xd1, 0x27, 0xf3, 0x5b, 0x18, 0x17, 0xa6, 0xa9, 0x4b, 0xdc, 0x44, 0xa4, 0xc0, 0x33, 0x38, 0xb5, + 0x48, 0xa4, 0x6a, 0xcc, 0xd8, 0x8c, 0xcd, 0x47, 0xe5, 0x4f, 0x99, 0x7f, 0x32, 0x98, 0xec, 0x92, + 0xe4, 0x5d, 0x43, 0xf8, 0x7b, 0x94, 0x5f, 0xc3, 0x84, 0xb0, 0xdd, 0x9a, 0x0a, 0x5f, 0x1a, 0x65, + 0x31, 0xfb, 0x9f, 0xbe, 0xc7, 0xdf, 0xbd, 0x47, 0x65, 0x91, 0x5f, 0xc1, 0x28, 0x18, 0x8b, 0x14, + 0x94, 0xf5, 0xd9, 0x60, 0xc6, 0xe6, 0x83, 0xb2, 0x6f, 0xf0, 0x29, 0x9c, 0xad, 0x1c, 0x85, 0x04, + 0x0f, 0x13, 0xbc, 0xaf, 0xef, 0x3f, 0x18, 0x5c, 0x2e, 0x93, 0xcb, 0x53, 0xe7, 0xb2, 0xdc, 0xab, + 0xf0, 0x35, 0x0c, 0xbb, 0x05, 0xb9, 0x14, 0x7f, 0x7b, 0x8b, 0x03, 0xe9, 0xe9, 0xdd, 0xf1, 0xc0, + 0xce, 0x3d, 0xff, 0xb7, 0x58, 0xc3, 0x4d, 0xe5, 0xec, 0x11, 0xe0, 0xe2, 0xbc, 0x5f, 0xb1, 0xe8, + 0xce, 0x52, 0xb0, 0x67, 0x51, 0x9b, 0xb0, 0x8a, 0x5a, 0x54, 0xce, 0xca, 0x6e, 0x82, 0x3c, 0x40, + 0x65, 0x8f, 0xca, 0x74, 0x46, 0xaf, 0xf5, 0x49, 0x7a, 0x3c, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, + 0x84, 0xb6, 0x23, 0xbd, 0xe3, 0x01, 0x00, 0x00, }, } func init() { yarpc.RegisterClientBuilder( - func(clientConfig transport.ClientConfig, structField reflect.StructField) SpeculatorServiceYARPCClient { - return NewSpeculatorServiceYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) + func(clientConfig transport.ClientConfig, structField reflect.StructField) SubmitQueueSpeculatorYARPCClient { + return NewSubmitQueueSpeculatorYARPCClient(clientConfig, protobuf.ClientBuilderOptions(clientConfig, structField)...) }, ) } diff --git a/speculator/protopb/speculator_grpc.pb.go b/speculator/protopb/speculator_grpc.pb.go index e9c06427..0713e3da 100644 --- a/speculator/protopb/speculator_grpc.pb.go +++ b/speculator/protopb/speculator_grpc.pb.go @@ -19,107 +19,107 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - SpeculatorService_Ping_FullMethodName = "/uber.devexp.submitqueue.speculator.SpeculatorService/Ping" + SubmitQueueSpeculator_Ping_FullMethodName = "/uber.devexp.submitqueue.speculator.SubmitQueueSpeculator/Ping" ) -// SpeculatorServiceClient is the client API for SpeculatorService service. +// SubmitQueueSpeculatorClient is the client API for SubmitQueueSpeculator service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // -// SpeculatorService provides the speculator API -type SpeculatorServiceClient interface { +// SubmitQueueSpeculator provides the speculator API +type SubmitQueueSpeculatorClient interface { // Ping returns a response indicating the service is alive Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) } -type speculatorServiceClient struct { +type submitQueueSpeculatorClient struct { cc grpc.ClientConnInterface } -func NewSpeculatorServiceClient(cc grpc.ClientConnInterface) SpeculatorServiceClient { - return &speculatorServiceClient{cc} +func NewSubmitQueueSpeculatorClient(cc grpc.ClientConnInterface) SubmitQueueSpeculatorClient { + return &submitQueueSpeculatorClient{cc} } -func (c *speculatorServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { +func (c *submitQueueSpeculatorClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingResponse) - err := c.cc.Invoke(ctx, SpeculatorService_Ping_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, SubmitQueueSpeculator_Ping_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -// SpeculatorServiceServer is the server API for SpeculatorService service. -// All implementations must embed UnimplementedSpeculatorServiceServer +// SubmitQueueSpeculatorServer is the server API for SubmitQueueSpeculator service. +// All implementations must embed UnimplementedSubmitQueueSpeculatorServer // for forward compatibility. // -// SpeculatorService provides the speculator API -type SpeculatorServiceServer interface { +// SubmitQueueSpeculator provides the speculator API +type SubmitQueueSpeculatorServer interface { // Ping returns a response indicating the service is alive Ping(context.Context, *PingRequest) (*PingResponse, error) - mustEmbedUnimplementedSpeculatorServiceServer() + mustEmbedUnimplementedSubmitQueueSpeculatorServer() } -// UnimplementedSpeculatorServiceServer must be embedded to have +// UnimplementedSubmitQueueSpeculatorServer must be embedded to have // forward compatible implementations. // // NOTE: this should be embedded by value instead of pointer to avoid a nil // pointer dereference when methods are called. -type UnimplementedSpeculatorServiceServer struct{} +type UnimplementedSubmitQueueSpeculatorServer struct{} -func (UnimplementedSpeculatorServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { +func (UnimplementedSubmitQueueSpeculatorServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } -func (UnimplementedSpeculatorServiceServer) mustEmbedUnimplementedSpeculatorServiceServer() {} -func (UnimplementedSpeculatorServiceServer) testEmbeddedByValue() {} +func (UnimplementedSubmitQueueSpeculatorServer) mustEmbedUnimplementedSubmitQueueSpeculatorServer() {} +func (UnimplementedSubmitQueueSpeculatorServer) testEmbeddedByValue() {} -// UnsafeSpeculatorServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to SpeculatorServiceServer will +// UnsafeSubmitQueueSpeculatorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SubmitQueueSpeculatorServer will // result in compilation errors. -type UnsafeSpeculatorServiceServer interface { - mustEmbedUnimplementedSpeculatorServiceServer() +type UnsafeSubmitQueueSpeculatorServer interface { + mustEmbedUnimplementedSubmitQueueSpeculatorServer() } -func RegisterSpeculatorServiceServer(s grpc.ServiceRegistrar, srv SpeculatorServiceServer) { - // If the following call pancis, it indicates UnimplementedSpeculatorServiceServer was +func RegisterSubmitQueueSpeculatorServer(s grpc.ServiceRegistrar, srv SubmitQueueSpeculatorServer) { + // If the following call pancis, it indicates UnimplementedSubmitQueueSpeculatorServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { t.testEmbeddedByValue() } - s.RegisterService(&SpeculatorService_ServiceDesc, srv) + s.RegisterService(&SubmitQueueSpeculator_ServiceDesc, srv) } -func _SpeculatorService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _SubmitQueueSpeculator_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PingRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SpeculatorServiceServer).Ping(ctx, in) + return srv.(SubmitQueueSpeculatorServer).Ping(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: SpeculatorService_Ping_FullMethodName, + FullMethod: SubmitQueueSpeculator_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SpeculatorServiceServer).Ping(ctx, req.(*PingRequest)) + return srv.(SubmitQueueSpeculatorServer).Ping(ctx, req.(*PingRequest)) } return interceptor(ctx, in, info, handler) } -// SpeculatorService_ServiceDesc is the grpc.ServiceDesc for SpeculatorService service. +// SubmitQueueSpeculator_ServiceDesc is the grpc.ServiceDesc for SubmitQueueSpeculator service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var SpeculatorService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "uber.devexp.submitqueue.speculator.SpeculatorService", - HandlerType: (*SpeculatorServiceServer)(nil), +var SubmitQueueSpeculator_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "uber.devexp.submitqueue.speculator.SubmitQueueSpeculator", + HandlerType: (*SubmitQueueSpeculatorServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Ping", - Handler: _SpeculatorService_Ping_Handler, + Handler: _SubmitQueueSpeculator_Ping_Handler, }, }, Streams: []grpc.StreamDesc{},