From 0f2a2a3075c3bd32c72dee22c0631e4bf252a374 Mon Sep 17 00:00:00 2001 From: Dmitriy Gertsog Date: Thu, 12 Dec 2024 19:36:15 +0300 Subject: [PATCH] aeon: mock gRPC server Mock server Implement some base methods for integration tests. Part of #1050, #1049 --- .github/workflows/full-ci.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/tests.yml | 2 +- .github/workflows/update.yml | 2 +- go.mod | 26 +-- go.sum | 67 ++++---- test/integration/aeon/conftest.py | 88 ++++++++++ test/integration/aeon/generate-keys.sh | 37 +++++ test/integration/aeon/server/.gitignore | 1 + test/integration/aeon/server/go.mod | 28 ++++ test/integration/aeon/server/go.sum | 71 ++++++++ test/integration/aeon/server/mock.go | 135 ++++++++++++++++ test/integration/aeon/server/service/diag.go | 17 ++ .../integration/aeon/server/service/server.go | 72 +++++++++ test/integration/aeon/test_aeon.py | 151 ++++++++++++------ test/integration/aeon/testdata/ca.key | 1 - test/integration/aeon/testdata/certfile.key | 1 - test/integration/aeon/testdata/private.key | 1 - 18 files changed, 606 insertions(+), 98 deletions(-) create mode 100644 test/integration/aeon/conftest.py create mode 100755 test/integration/aeon/generate-keys.sh create mode 100644 test/integration/aeon/server/.gitignore create mode 100644 test/integration/aeon/server/go.mod create mode 100644 test/integration/aeon/server/go.sum create mode 100644 test/integration/aeon/server/mock.go create mode 100644 test/integration/aeon/server/service/diag.go create mode 100644 test/integration/aeon/server/service/server.go delete mode 100644 test/integration/aeon/testdata/ca.key delete mode 100644 test/integration/aeon/testdata/certfile.key delete mode 100644 test/integration/aeon/testdata/private.key diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index ac2e4a347..8da41f8ad 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -11,7 +11,7 @@ on: env: # Note: Use exactly match version of tool, to avoid unexpected issues with test on CI. - GO_VERSION: '1.21.13' + GO_VERSION: '1.22.10' PYTHON_VERSION: '3.10' jobs: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 97cbfe2fc..ee99df1d1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ on: env: # Note: Use exactly match version of tool, to avoid unexpected issues with test on CI. - GO_VERSION: '1.21.13' + GO_VERSION: '1.22.10' jobs: create-packages-linux: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8f0d3c9e9..1b575bcb8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,7 @@ on: env: # Note: Use exactly match version of tool, to avoid unexpected issues with test on CI. - GO_VERSION: '1.21.13' + GO_VERSION: '1.22.10' PYTHON_VERSION: '3.10' jobs: diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index acca06309..31424e5d3 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -9,7 +9,7 @@ on: env: # Note: Use exactly match version of tool, to avoid unexpected issues with test on CI. - GO_VERSION: '1.21.13' + GO_VERSION: '1.22.10' jobs: update: diff --git a/go.mod b/go.mod index 725e3e42b..011c725ed 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/tarantool/tt -go 1.21 +go 1.22 require ( github.com/adam-hanna/arrayOperations v0.2.6 @@ -10,7 +10,7 @@ require ( github.com/dave/jennifer v1.5.0 github.com/docker/docker v26.1.5+incompatible github.com/fatih/color v1.13.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-version v1.4.0 github.com/jedib0t/go-pretty/v6 v6.4.6 github.com/magefile/mage v1.12.1 @@ -22,7 +22,7 @@ require ( github.com/nxadm/tail v1.4.11 github.com/otiai10/copy v1.14.0 github.com/spf13/cobra v1.8.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/tarantool/cartridge-cli v0.0.0-20220605082730-53e6a5be9a61 github.com/tarantool/go-prompt v1.0.1 github.com/tarantool/go-tarantool v1.12.2 @@ -38,6 +38,8 @@ require ( golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/sys v0.28.0 golang.org/x/term v0.27.0 + google.golang.org/grpc v1.69.0 + google.golang.org/protobuf v1.36.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -51,7 +53,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/c-bata/go-prompt v0.2.6 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/containerd/containerd v1.6.26 // indirect github.com/containerd/log v0.1.0 // indirect @@ -65,7 +67,7 @@ require ( github.com/fatih/structs v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -126,13 +128,13 @@ require ( go.etcd.io/etcd/server/v3 v3.5.12 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect @@ -143,10 +145,8 @@ require ( golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect - google.golang.org/grpc v1.61.1 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 // indirect gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index 6aacc3761..c8d7cfa8f 100644 --- a/go.sum +++ b/go.sum @@ -21,9 +21,8 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -82,8 +81,8 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -92,8 +91,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs= @@ -133,8 +132,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= +github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -156,8 +155,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= @@ -229,8 +228,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= @@ -426,8 +425,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tarantool/go-openssl v0.0.8-0.20230307065445-720eeb389195/go.mod h1:M7H4xYSbzqpW/ZRBMyH0eyqQBsnhAMfsYk5mv0yid7A= github.com/tarantool/go-openssl v1.1.1 h1:qOCSjUXRLxlnh0e2G6sH50B3d/gYpscbY/opFqsIfaE= github.com/tarantool/go-openssl v1.1.1/go.mod h1:M7H4xYSbzqpW/ZRBMyH0eyqQBsnhAMfsYk5mv0yid7A= @@ -493,20 +492,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= -go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -607,8 +608,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= @@ -810,10 +811,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos= google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 h1:Z7FRVJPSMaHQxD0uXU8WdgFh8PseLM8Q8NzhnpMrBhQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -827,8 +828,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI= +google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= 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= @@ -841,8 +842,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/integration/aeon/conftest.py b/test/integration/aeon/conftest.py new file mode 100644 index 000000000..4666ac35a --- /dev/null +++ b/test/integration/aeon/conftest.py @@ -0,0 +1,88 @@ +import os +from pathlib import Path +from signal import SIGQUIT +from subprocess import PIPE, STDOUT, Popen, run + +import pytest + +from utils import wait_for_lines_in_output + + +@pytest.fixture(scope="session") +def certificates(tmp_path_factory: pytest.TempPathFactory) -> dict[str, Path]: + dir = tmp_path_factory.mktemp("aeon_cert") + cmd = (Path(__file__).parent / "generate-keys.sh", dir) + returncode = run(cmd).returncode + assert returncode == 0, "Some error on generate certificates" + cert = { + "ca": dir / "ca.crt", + "s_private": dir / "server.key", + "s_public": dir / "server.crt", + "c_private": dir / "client.key", + "c_public": dir / "client.crt", + } + for k, v in cert.items(): + assert v.exists(), f"Not found {k} certificate" + return cert + + +@pytest.fixture(scope="session") +def mock_aeon(tmp_path_factory) -> Path: + server_dir = Path(__file__).parent / "server" + exec = tmp_path_factory.mktemp("aeon_mock") / "aeon" + result = run(f"go build -C {server_dir} -o {exec}".split()) + assert result.returncode == 0, "Failed build mock aeon server" + return exec + + +@pytest.fixture(params=[50052, "@aeon_unix_socket", "AEON"]) +def aeon_plain(mock_aeon, tmp_path, request): + cmd = [mock_aeon] + param = request.param + if isinstance(param, int): + cmd.append(f"-port={param}") + elif isinstance(param, str): + if param[0] != "@": + param = tmp_path / param + cmd.append(f"-unix={param}") + + aeon = Popen( + cmd, + env=dict(os.environ, GRPC_GO_LOG_SEVERITY_LEVEL="info"), + stderr=STDOUT, + stdout=PIPE, + text=True, + ) + print(wait_for_lines_in_output(aeon.stdout, ["ListenSocket created"])) + yield param + aeon.send_signal(SIGQUIT) + assert aeon.wait(5) == 0, "Mock aeon server didn't stopped properly" + + +@pytest.fixture(params=["server-side", "mutual-tls"]) +def aeon_ssl(mock_aeon, certificates, request): + cmd = [ + mock_aeon, + "-ssl", + f"-key={certificates['s_private']}", + f"-cert={certificates['s_public']}", + ] + mode = request.param + if mode == "mutual-tls": + cmd.append(f"-ca={certificates['ca']}") + elif mode == "server-side": + pass + else: + assert False, "Unsupported TLS mode" + + aeon = Popen( + cmd, + env=dict(os.environ, GRPC_GO_LOG_SEVERITY_LEVEL="info"), + stderr=STDOUT, + stdout=PIPE, + text=True, + ) + print(wait_for_lines_in_output(aeon.stdout, ["ListenSocket created"])) + yield mode + aeon.send_signal(SIGQUIT) + assert aeon.wait(5) == 0, "Mock aeon ssl server didn't stopped properly" diff --git a/test/integration/aeon/generate-keys.sh b/test/integration/aeon/generate-keys.sh new file mode 100755 index 000000000..1b866a212 --- /dev/null +++ b/test/integration/aeon/generate-keys.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -e + +### First argument is target directory where generate files. +DIR=$(realpath ${1:-$(pwd)}) +[ -d $DIR ] || mkdir -p $DIR +cd $DIR + +CA_SUBJ="/C=RU/ST=State/L=TestCity/O=Integration test/OU=Aeon/CN=localhost" + +cat > ext.cnf << EOF +subjectAltName = @alt_names +[alt_names] +DNS = localhost +IP = 127.0.0.1 +EOF + +### Server .key, .crt and ca.crt required for Server-Side TLS mode. + +# 1. Generate CA's private key and self-signed certificate +openssl req -new -x509 -days 1 -noenc -keyout ca.key -out ca.crt -subj "${CA_SUBJ}" + +# 2. Generate web server's private key and certificate signing request (CSR) +openssl req -new -noenc -keyout server.key -out server.csr -subj "${CA_SUBJ}" + +# 3. Use CA's private key to sign web server's CSR and get back the signed certificate +openssl x509 -req -in server.csr -days 1 -CA ca.crt -CAkey ca.key -CAcreateserial \ + -out server.crt -extfile ext.cnf + +### Client .key & .crt required for Mutual TSL mode. + +# 4. Generate client's private key and certificate signing request (CSR) +openssl req -new -noenc -keyout client.key -out client.csr -subj "$CA_SUBJ" + +# 5. Use CA's private key to sign client's CSR and get back the signed certificate +openssl x509 -req -in client.csr -days 1 -CA ca.crt -CAkey ca.key -CAcreateserial \ + -out client.crt -extfile ext.cnf diff --git a/test/integration/aeon/server/.gitignore b/test/integration/aeon/server/.gitignore new file mode 100644 index 000000000..3a28e923e --- /dev/null +++ b/test/integration/aeon/server/.gitignore @@ -0,0 +1 @@ +aeon diff --git a/test/integration/aeon/server/go.mod b/test/integration/aeon/server/go.mod new file mode 100644 index 000000000..8ffb92175 --- /dev/null +++ b/test/integration/aeon/server/go.mod @@ -0,0 +1,28 @@ +module mock/server/aeon + +go 1.22.8 + +require ( + github.com/google/uuid v1.6.0 + github.com/tarantool/go-tarantool/v2 v2.2.0 + github.com/tarantool/tt v0.0.0 + google.golang.org/grpc v1.69.0 +) + +require ( + github.com/jedib0t/go-pretty/v6 v6.4.6 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 // indirect + google.golang.org/protobuf v1.36.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +replace github.com/tarantool/tt => ../../../../ diff --git a/test/integration/aeon/server/go.sum b/test/integration/aeon/server/go.sum new file mode 100644 index 000000000..db906a216 --- /dev/null +++ b/test/integration/aeon/server/go.sum @@ -0,0 +1,71 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jedib0t/go-pretty/v6 v6.4.6 h1:v6aG9h6Uby3IusSSEjHaZNXpHFhzqMmjXcPq1Rjl9Jw= +github.com/jedib0t/go-pretty/v6 v6.4.6/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tarantool/go-iproto v1.1.0 h1:HULVOIHsiehI+FnHfM7wMDntuzUddO09DKqu2WnFQ5A= +github.com/tarantool/go-iproto v1.1.0/go.mod h1:LNCtdyZxojUed8SbOiYHoc3v9NvaZTB7p96hUySMlIo= +github.com/tarantool/go-tarantool/v2 v2.2.0 h1:U7RDvWxPaPPecMppqVwfpTGnSJQ++Crg2l9cS/ztgp8= +github.com/tarantool/go-tarantool/v2 v2.2.0/go.mod h1:hKKeZeCP8Y8+U6ZFS32ot1jHV/n4WKVP4fjRAvQznMY= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sys v0.1.0/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/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 h1:Z7FRVJPSMaHQxD0uXU8WdgFh8PseLM8Q8NzhnpMrBhQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= +google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI= +google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/test/integration/aeon/server/mock.go b/test/integration/aeon/server/mock.go new file mode 100644 index 000000000..ade2970ac --- /dev/null +++ b/test/integration/aeon/server/mock.go @@ -0,0 +1,135 @@ +package main + +import ( + "crypto/tls" + "crypto/x509" + "flag" + "fmt" + "log" + "mock/server/aeon/service" + "net" + "os" + "os/signal" + "strings" + "sync" + "syscall" + + "github.com/tarantool/tt/cli/aeon/pb" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" +) + +var args = struct { + is_ssl *bool + ca_file *string + cert_file *string + key_file *string + port *int + unix_socket *string +}{ + is_ssl: flag.Bool("ssl", false, "Connection uses SSL if set, (default plain TCP)"), + ca_file: flag.String("ca", "", "The CA file"), + cert_file: flag.String("cert", "", "The TLS cert file"), + key_file: flag.String("key", "", "The TLS key file"), + port: flag.Int("port", 50051, "The server port"), + unix_socket: flag.String("unix", "", "The Unix socket name"), +} + +func getCertificate() tls.Certificate { + if *args.cert_file == "" || *args.key_file == "" { + log.Fatalln("Both 'key_file' and 'cert_file' required") + } + tls_cert, err := tls.LoadX509KeyPair(*args.cert_file, *args.key_file) + if err != nil { + log.Fatalf("Could not load server key pair: %v", err) + } + return tls_cert +} + +func getTlsConfig() *tls.Config { + if *args.ca_file == "" { + return &tls.Config{ + Certificates: []tls.Certificate{getCertificate()}, + ClientAuth: tls.NoClientCert, + } + } + + ca, err := os.ReadFile(*args.ca_file) + if err != nil { + log.Fatalf("Failed to read CA file: %v", err) + } + certPool := x509.NewCertPool() + if !certPool.AppendCertsFromPEM(ca) { + log.Fatalln("Failed to append CA data") + } + return &tls.Config{ + Certificates: []tls.Certificate{getCertificate()}, + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: certPool, + } +} + +func getServerOpts() []grpc.ServerOption { + if !*args.is_ssl { + return []grpc.ServerOption{} + } + creds := credentials.NewTLS(getTlsConfig()) + return []grpc.ServerOption{grpc.Creds(creds)} +} + +func getListener() net.Listener { + var protocol string + var address string + + if *args.unix_socket != "" { + protocol = "unix" + address = *args.unix_socket + if strings.HasPrefix(address, "@") { + address = "\x00" + address[1:] + } + } else { + protocol = "tcp" + address = fmt.Sprintf("localhost:%d", *args.port) + } + lis, err := net.Listen(protocol, address) + if err != nil { + log.Fatalf("Failed to listen: %v", err) + } + return lis +} + +func main() { + log.Println("Start aeon mock server:", os.Args) + + flag.Parse() + + srv := grpc.NewServer(getServerOpts()...) + pb.RegisterSQLServiceServer(srv, &service.Server{}) + pb.RegisterDiagServiceServer(srv, &service.Diag{}) + + // Run gRPC server. + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + if err := srv.Serve(getListener()); err != nil { + log.Fatalf("Failed to serve: %v", err) + } + wg.Done() + }() + + // Shutdown on signals. + exit_sig := make(chan os.Signal, 1) + signal.Notify(exit_sig, + syscall.SIGTERM, + syscall.SIGINT, + syscall.SIGQUIT, + syscall.SIGHUP, + ) + s := <-exit_sig + log.Println("Got terminate signal:", s) + + srv.GracefulStop() + wg.Wait() + log.Println("Exit aeon mock server.") +} diff --git a/test/integration/aeon/server/service/diag.go b/test/integration/aeon/server/service/diag.go new file mode 100644 index 000000000..d6b7c3cdb --- /dev/null +++ b/test/integration/aeon/server/service/diag.go @@ -0,0 +1,17 @@ +package service + +import ( + "context" + + "github.com/tarantool/tt/cli/aeon/pb" +) + +// Diag mock implementation of pb.DiagServiceServer. +type Diag struct { + pb.UnimplementedDiagServiceServer +} + +// Ping implements pb.DiagServiceServer.Ping method. +func (s *Diag) Ping(ctx context.Context, in *pb.PingRequest) (*pb.PingResponse, error) { + return &pb.PingResponse{}, nil +} diff --git a/test/integration/aeon/server/service/server.go b/test/integration/aeon/server/service/server.go new file mode 100644 index 000000000..f8447f4b1 --- /dev/null +++ b/test/integration/aeon/server/service/server.go @@ -0,0 +1,72 @@ +package service + +import ( + "context" + "strings" + + "github.com/tarantool/tt/cli/aeon/pb" +) + +// Server mock functions: SQL[Check|Stream] accepts SQL request with string ["ok", "error", ""]. +// SQLCheck returns appropriate SQLCheckStatus value: "VALID", "INVALID", "INCOMPLETE". +// SQL[Stream] returns SQLResponse with two tuples on "ok" request and with Error other way. +type Server struct { + pb.UnimplementedSQLServiceServer +} + +func (s *Server) SQLCheck(ctx context.Context, + request *pb.SQLRequest) (*pb.SQLCheckResponse, error) { + status := pb.SQLCheckStatus_SQL_QUERY_INCOMPLETE + switch strings.ToLower(request.Query) { + case "ok": + status = pb.SQLCheckStatus_SQL_QUERY_VALID + case "error": + status = pb.SQLCheckStatus_SQL_QUERY_INVALID + } + return &pb.SQLCheckResponse{Status: status}, nil +} + +func (s *Server) SQL(ctx context.Context, in *pb.SQLRequest) (*pb.SQLResponse, error) { + res := makeSQLResponse(in.Query) + return &res, nil +} + +func (s *Server) SQLStream(in *pb.SQLRequest, stream pb.SQLService_SQLStreamServer) error { + res := makeSQLResponse(in.Query) + stream.Send(&res) + return nil +} + +func makeSQLResponse(query string) pb.SQLResponse { + switch strings.ToLower(query) { + case "ok": + return pb.SQLResponse{ + TupleFormat: &pb.TupleFormat{Names: []string{"id", "name"}}, + Tuples: []*pb.Tuple{ + { + Fields: []*pb.Value{ + {Kind: &pb.Value_IntegerValue{IntegerValue: 1}}, + {Kind: &pb.Value_StringValue{StringValue: "entry1"}}, + }, + }, + { + Fields: []*pb.Value{ + {Kind: &pb.Value_IntegerValue{IntegerValue: 2}}, + {Kind: &pb.Value_StringValue{StringValue: "entry2"}}, + }, + }, + }, + } + case "error": + return pb.SQLResponse{Error: &pb.Error{ + Type: "AeonSQLError", + Name: "SYNTAX_ERROR", + Msg: "error in mock SQL request", + }} + } + return pb.SQLResponse{Error: &pb.Error{ + Type: "AeonError", + Name: "UNEXPECTED_ERROR", + Msg: "incomplete in mock SQL request", + }} +} diff --git a/test/integration/aeon/test_aeon.py b/test/integration/aeon/test_aeon.py index faeb567cb..4022f03ac 100644 --- a/test/integration/aeon/test_aeon.py +++ b/test/integration/aeon/test_aeon.py @@ -1,135 +1,196 @@ #!/usr/bin/env python3 -from pathlib import Path from subprocess import PIPE, STDOUT, run import pytest AeonConnectCommand = ("aeon", "connect") -FormatData = { - "testdata": Path(__file__).parent / "testdata", -} + +def check_tt_aeon_response(output: str): + expected = ["Aeon responses at", "Processing piped input", "EOF on pipe"] + logs = output.split("\n") + for line in logs: + print(line) + for e in expected: + if e in line: + expected.remove(e) + break + if len(expected) == 0: + return + + assert False, f"Not found all expected Log records: {expected}" @pytest.mark.parametrize( "args", [ - (), ("--transport", "plain"), - ("--transport=plain"), + ("--transport=plain",), # "plain" mode ignores any ssl flags values. ("--transport", "plain", "--sslkeyfile", "not-exits.key"), ("--transport", "plain", "--sslcertfile", "not-exits.key"), ("--transport", "plain", "--sslcafile", "not-exits.key"), - ("--transport", "plain", "--sslkeyfile", "{testdata}/private.key"), - ("--transport", "plain", "--sslcertfile", "{testdata}/certfile.key"), - ("--transport", "plain", "--sslcafile", "{testdata}/ca.key"), - ( - "--sslkeyfile={testdata}/private.key", - "--sslcertfile={testdata}/certfile.key", - ), - ( - # "ssl" mode require existed path to files. - "--transport=ssl", - "--sslkeyfile={testdata}/private.key", - "--sslcertfile={testdata}/certfile.key", - "--sslcafile={testdata}/ca.key", - ), + ("--transport", "plain", "--sslkeyfile", "{c_private}"), + ("--transport", "plain", "--sslcertfile", "{c_public}"), + ("--transport", "plain", "--sslcafile", "{ca}"), ], ) -def test_cli_arguments_success(tt_cmd, args): - args = (a.format(**FormatData) for a in args) - result = run((tt_cmd, *AeonConnectCommand, *args)) - assert result.returncode == 0 +def test_cli_plain_arguments_success(tt_cmd, aeon_plain, certificates, args): + cmd = [str(tt_cmd), *AeonConnectCommand] + cmd += (a.format(**certificates) for a in args) + print(f"Aeon plain at: {aeon_plain}") + if isinstance(aeon_plain, int): + cmd.append(f"localhost:{aeon_plain}") + else: + cmd.append(f"unix://{aeon_plain}") + + print(f"Run: {' '.join(cmd)}") + tt = run( + cmd, + capture_output=True, + input="", + text=True, + encoding="utf-8", + ) + check_tt_aeon_response(tt.stderr) + assert tt.returncode == 0 + + +def test_cli_ssl_arguments_success(tt_cmd, aeon_ssl, certificates): + cmd = [str(tt_cmd), *AeonConnectCommand, f"--sslcafile={certificates['ca']}"] + print(f"Aeon ssl mode: {aeon_ssl}") + if aeon_ssl == "mutual-tls": + cmd += ( + f"--sslkeyfile={certificates['c_private']}", + f"--sslcertfile={certificates['c_public']}", + ) + elif aeon_ssl == "server-side": + cmd += ("--transport", "ssl") + + cmd.append("localhost:50051") + + print(f"Run: {' '.join(cmd)}") + tt = run( + cmd, + capture_output=True, + input="", + text=True, + encoding="utf-8", + ) + check_tt_aeon_response(tt.stderr) + assert tt.returncode == 0 @pytest.mark.parametrize( "args, error", [ + ((), "Error: accepts 1 arg(s), received 0"), ( - ("--transport", "mode"), + ("localhost:50051", "@aeon_unix_socket"), + "Error: accepts 1 arg(s), received 2", + ), + ( + ( + "--transport", + "mode", + "localhost:50051", + ), 'Error: invalid argument "mode" for "--transport" flag', ), ( ( "--transport=ssl", "--sslkeyfile=not-exits.key", - "--sslcertfile={testdata}/certfile.key", - "--sslcafile={testdata}/ca.key", + "--sslcertfile={c_public}", + "--sslcafile={ca}", + "localhost:50051", ), 'not valid path to a private SSL key file="not-exits.key"', ), ( ( "--transport=ssl", - "--sslkeyfile={testdata}/private.key", + "--sslkeyfile={c_private}", "--sslcertfile=not-exits.key", - "--sslcafile={testdata}/ca.key", + "--sslcafile={ca}", + "localhost:50051", ), 'not valid path to an SSL certificate file="not-exits.key"', ), ( ( "--transport=ssl", - "--sslkeyfile={testdata}/private.key", - "--sslcertfile={testdata}/certfile.key", + "--sslkeyfile={c_private}", + "--sslcertfile={c_public}", "--sslcafile=not-exits.key", + "localhost:50051", ), 'not valid path to trusted certificate authorities (CA) file="not-exits.key"', ), ( - ("--sslcafile=not-exits.key",), + ( + "--sslcafile=not-exits.key", + "localhost:50051", + ), 'not valid path to trusted certificate authorities (CA) file="not-exits.key"', ), ( ( "--transport=ssl", - "--sslcertfile={testdata}/certfile.key", - "--sslcafile={testdata}/ca.key", + "--sslcertfile={c_public}", + "--sslcafile={ca}", + "localhost:50051", ), "files Key and Cert must be specified both", ), ( ( "--transport=ssl", - "--sslkeyfile={testdata}/private.key", - "--sslcafile={testdata}/ca.key", + "--sslkeyfile={c_private}", + "--sslcafile={ca}", + "localhost:50051", ), "files Key and Cert must be specified both", ), ( ( + "localhost:50051", "--transport=ssl", - "--sslcertfile={testdata}/certfile.key", - "--sslcafile={testdata}/ca.key", + "--sslcertfile={c_public}", + "--sslcafile={ca}", "--sslkeyfile", ), "flag needs an argument: --sslkeyfile", ), ( ( + "localhost:50051", "--transport=ssl", - "--sslkeyfile={testdata}/private.key", - "--sslcafile={testdata}/ca.key", + "--sslkeyfile={c_private}", + "--sslcafile={ca}", "--sslcertfile", ), "flag needs an argument: --sslcertfile", ), ( ( + "localhost:50051", "--transport=ssl", - "--sslkeyfile={testdata}/private.key", - "--sslcertfile={testdata}/certfile.key", + "--sslkeyfile={c_private}", + "--sslcertfile={c_public}", "--sslcafile", ), "flag needs an argument: --sslcafile", ), ], ) -def test_cli_arguments_fail(tt_cmd, args, error): - args = (a.format(**FormatData) for a in args) +def test_cli_arguments_fail(tt_cmd, certificates, args, error): + cmd = [str(tt_cmd), *AeonConnectCommand] + cmd += (a.format(**certificates) for a in args) + + print(f"Run: {' '.join(cmd)}") result = run( - (tt_cmd, *AeonConnectCommand, *args), + cmd, stderr=STDOUT, stdout=PIPE, text=True, diff --git a/test/integration/aeon/testdata/ca.key b/test/integration/aeon/testdata/ca.key deleted file mode 100644 index 93d503f39..000000000 --- a/test/integration/aeon/testdata/ca.key +++ /dev/null @@ -1 +0,0 @@ -# trusted certificate authorities (CA) file diff --git a/test/integration/aeon/testdata/certfile.key b/test/integration/aeon/testdata/certfile.key deleted file mode 100644 index eb26018b7..000000000 --- a/test/integration/aeon/testdata/certfile.key +++ /dev/null @@ -1 +0,0 @@ -# SSL certificate file diff --git a/test/integration/aeon/testdata/private.key b/test/integration/aeon/testdata/private.key deleted file mode 100644 index 522386ee1..000000000 --- a/test/integration/aeon/testdata/private.key +++ /dev/null @@ -1 +0,0 @@ -# private SSL key file