[testcontainers] Support both TQE 2.x and TQE 3.x versions#86
[testcontainers] Support both TQE 2.x and TQE 3.x versions#86dkasimovskiy wants to merge 1 commit into
Conversation
4931800 to
e323bb8
Compare
bcdb62d to
4d5c877
Compare
- Collapse AbstractTQECluster/{TQE2ClusterImpl,TQE3ClusterImpl} into a
single TQEClusterImpl (TQE3 startup order is safe for both versions).
- Unify GrpcRole.PRODUCER with "publisher" alias; drop PUBLISHER constant.
- Revert FileTQEConfigurator cosmetic changes: withClusterName/close
to master variants, image field last in Builder, default cluster name
generation back in withClusterName (with warn log).
- Rename dataForTestInvalidQueueConfig -> ...ShouldThrow to match
the pre-existing naming convention.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
….build() The build() fallback that generates a default cluster name when none was provided via withClusterName() was inadvertently dropped while addressing PR #86 review comment #7. Test fixtures (TQEClusterFixture, TQEClusterTest, FileTQEConfiguratorTest.simpleConfiguration) do not call withClusterName() explicitly, so removing the fallback made the cluster name "null" appear in container names (e.g. "/router-null"), which then collided on parallel/repeated runs. Restore the defensive fallback in build() so the configurator is always valid, while keeping the warn-logged fallback in withClusterName() for explicit callers (per the review comment resolution). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…meterized tests Add TQE 3.x (message-queue-ee 3.x) integration on top of the existing TQE 2.x support in testcontainers. Refactor the resulting duplication into a single parameterized test suite driven by a per-version enum, versioned cluster and gRPC strategy implementations, and shared fixtures. - New TQE 3.x wiring: image, configs, ProducerServiceGrpc client, gRPC container, bidirectional subscription. - Versioned cluster/container builders via FileTQEConfigurator.tqe3Builder /tqe2Builder; single TQEClusterImpl (TQE 3.x startup order is safe for both versions). - GrpcRole.PRODUCER accepts "publisher" as alias (TQE 2.x naming) — eliminates the version-specific role constant. - Replace TQE2ClusterImplTest + TQE3ClusterImplTest with TQEClusterIntegrationTest + TQEClusterTest parameterized over TQEVersion. - Extract GrpcTestStrategy interface with TQE2/TQE3 implementations to isolate version-specific gRPC API differences. - TQEVersion encapsulates image, configs, role names, builder/cluster factories, and gRPC strategy per version (OCP-friendly — adding a future TQE 4.x is a single new enum constant). - Migrate protobuf generation from xolstice to ascopes plugin; rename proto/config resource directories to tqe2/tqe3. - Fix GrpcContainerImpl.validateConfigPath: path.toString().endsWith() instead of Path.endsWith (path-component comparison) so the .yml extension check actually works as the error message claims. Addresses PR #86 review comments. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
296b8c8 to
6c74965
Compare
| this.grpcConfigs = new LinkedHashSet<>(grpcConfigs); | ||
| } | ||
|
|
||
| public Builder withRouterRole(String routerRole) { |
There was a problem hiding this comment.
Судя по всему, пользователю достаточно того, что ему отдали на пользование методы tqe2builder и tqe3builder, а Builder.wthRouterRoles ему давать вообще в руки опасно - очепятается и укажет не то что нибудь.
Поэтому в аргументы метода private Builder(DockerImageName image, Path queueConfig, Collection<Path> grpcConfigs) можно расширить добавить еще и routerRoles, и его прямо на месте передавать, должно получиться так:
public static Builder tqe2Builder(
DockerImageName image, Path queueConfig, Collection<Path> grpcConfigs) {
return builder(image, queueConfig, grpcConfigs, TQE2_ROUTER_ROLE);
}
public static Builder tqe3Builder(
DockerImageName image, Path queueConfig, Collection<Path> grpcConfigs) {
return builder(image, queueConfig, grpcConfigs, TQE3_ROUTER_ROLE);
}| this.startupTimeout == null ? DEFAULT_STARTUP_TIMEOUT : this.startupTimeout; | ||
| final Duration bootstrapTimeout = | ||
| this.bootstrapTimeout == null ? DEFAULT_BOOTSTRAP_TIMEOUT : this.bootstrapTimeout; | ||
| if (this.routerRole == null) { |
There was a problem hiding this comment.
Если сделать так, как я предлагаю, без withRouterRole, то эта проверка не нужна - при вызове tqe2builder или tqe3builder роль всегда будет указана.
| return FileTQEConfigurator.tqe2Builder(imageName(), queue, grpc); | ||
| } | ||
|
|
||
| @Override |
There was a problem hiding this comment.
Этот метод теперь в объектах перечисления выглядит одинаково, и его можно вынести в код испытания, так как нет различий между 2 и 3 версией.
| this.strategy = strategy; | ||
| } | ||
|
|
||
| public String displayName() { |
There was a problem hiding this comment.
Как будто этот метод не используется
| private final String displayName; | ||
| private final String producerRoleName; | ||
| private final GrpcRole producerRole; | ||
| private final boolean requiresConfigure; |
There was a problem hiding this comment.
Кажется, что теперь это тоже не нужно, т.к. что 2, что 3 версии сперва собирают и запускают кластер тарантула, а потом уже запускают gRPC. Теперь никакиз различий нет, я думаю, этот атрибут можно убрать.
| } | ||
|
|
||
| @Override | ||
| public void subscribe(ManagedChannel channel, String queue, Set<User> result) { |
There was a problem hiding this comment.
А почему именно Set, а не Queue, List или Consumer?
А если нам нужно еще порядок сообщений проверить?
| } | ||
|
|
||
| @Override | ||
| public void subscribe(ManagedChannel channel, String queue, Set<User> result) { |
There was a problem hiding this comment.
Тот же самый вопрос про List, Queue или Consumer вместо Set.
| * PublisherServiceGrpc} + unidirectional streaming. TQE 3.x uses {@code ProducerGrpc} + | ||
| * bidirectional streaming. | ||
| */ | ||
| interface GrpcTestStrategy { |
There was a problem hiding this comment.
Я бы переназвал этот интерфейс просто как TQEClient, потому что это не стратегия, по большому счёту, а именно интерфейс клиента к TQE. Название запутывает
| /** | ||
| * Publishes a batch of users to the given queue over the channel. Synchronous: throws on failure. | ||
| */ | ||
| void publish(ManagedChannel channel, List<User> users, String queue) throws Exception; |
There was a problem hiding this comment.
По хорошему, ManagedChannel - это внутрянка клиента, её не надо выводить в интерфейс.
Нормальный интерфейс клиента к TQE (специально для тестов), должен выглядеть следующим образом:
void publish(List<User> users, String queue) throws Exception;
void subscribe(String queue, Consumer<User> resultAcceptor);| version.configuratorBuilder(version.queueConfig(), Set.of(version.grpcConfig())).build()) { | ||
| configurator.queue().values().parallelStream().forEach(Startable::start); | ||
| configurator.configure(); | ||
| if (version.requiresConfigure()) { |
There was a problem hiding this comment.
Поскольку разницы в настройке и запуске TQE между версиями теперь нет, можно убрать этот код и всегда делать configure().
В
testcontainersдобавлена поддержку двух версий TQE (2.x, 3.x).Консолидация тестов
TQEClusterIntegrationTest+TQEClusterTest(параметризованныечерез enum
TQEVersion) заменяют старыеTQE2ClusterImplTest+TQE3ClusterImplTestи абстрактные базовые классы.GrpcRole.PRODUCERтеперь принимает унаследованный от TQE 2.xалиас
"publisher", поэтому единыйTQEClusterImplработаетдля обеих версий, а
TQE2ClusterImpl/TQE3ClusterImplудалены.GrpcTestStrategyизолирует различия gRPC API (publish / Producer.produce,однонаправленная / двунаправленная подписка).
TQEVersionинкапсулирует образ, конфиги, имена ролей, фабрикиbuilder/cluster и gRPC-стратегию для каждой версии — добавление
будущей TQE 4.x сводится к одной новой константе enum'а.
Примечания
tdg2намеренно не затронута.xolsticeнаascopes;proto-файлы перенесены в
tqe2/иtqe3/.GrpcContainerImpl.validateConfigPathтеперь используетpath.toString().endsWith(".yml")(былPath.endsWith,сравнение компонентов пути) — проверка расширения теперь
действительно работает.
I haven't forgotten about:
Related issues: