korlov42 commented on code in PR #1483:
URL: https://github.com/apache/ignite-3/pull/1483#discussion_r1065890394


##########
modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java:
##########
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.framework;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.calcite.schema.Table;
+import org.apache.ignite.internal.schema.NativeType;
+import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
+import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptorImpl;
+import org.apache.ignite.internal.sql.engine.schema.DefaultValueStrategy;
+import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.apache.ignite.internal.sql.engine.schema.TableDescriptorImpl;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
+
+/**
+ * A collection of builders to create test objects.
+ */
+public class TestBuilders {
+    /** Returns a builder of the test cluster object. */
+    public static ClusterBuilder cluster() {
+        return new ClusterBuilderImpl();
+    }
+
+    /** Returns a builder of the test table object. */
+    public static TableBuilder table() {
+        return new TableBuilderImpl();
+    }
+
+    /**
+     * A builder to created a test cluster object.
+     *
+     * @see TestCluster
+     */
+    public interface ClusterBuilder {
+        /**
+         * Sets desired names for the cluster nodes.
+         *
+         * @param nodeNames An array of node names to create cluster from.
+         * @return {@code this} for chaining.
+         */
+        ClusterBuilder nodes(String... nodeNames);
+
+        /**
+         * Creates a table builder to add to the cluster.
+         *
+         * @return An instance of table builder.
+         */
+        ClusterTableBuilder addTable();
+
+        /**
+         * Builds the cluster object.
+         *
+         * @return Created cluster object.
+         */
+        TestCluster build();
+    }
+
+    /**
+     * A builder to created a test table object.
+     *
+     * @see TestTable
+     */
+    public interface TableBuilder extends TableBuilderBase<TableBuilder> {
+        /**
+         * Builds a table.
+         *
+         * @return Created table object.
+         */
+        public TestTable build();
+    }
+
+    /**
+     * A builder to created a test table as nested object of the cluster.
+     *
+     * @see TestTable
+     * @see TestCluster
+     */
+    public interface ClusterTableBuilder extends 
TableBuilderBase<ClusterTableBuilder>, NestedBuilder<ClusterBuilder> {
+    }
+
+    private static class ClusterBuilderImpl implements ClusterBuilder {
+        private final List<TestTable> tables = new ArrayList<>();
+        private List<String> nodeNames;
+
+        @Override
+        public ClusterBuilder nodes(String... nodeNames) {
+            this.nodeNames = List.of(nodeNames);
+
+            return this;
+        }
+
+        @Override
+        public ClusterTableBuilder addTable() {
+            return new ClusterTableBuilderImpl(this);
+        }
+
+        @Override
+        public TestCluster build() {
+            var clusterService = new TestClusterService(nodeNames);
+
+            Map<String, Table> tableMap = tables.stream()
+                    .collect(Collectors.toMap(TestTable::name, 
Function.identity()));
+
+            var schemaManager = new PredefinedSchemaManager(new 
IgniteSchema("PUBLIC", tableMap, null));
+
+            Map<String, TestNode> nodes = nodeNames.stream()
+                    .map(name -> new TestNode(name, 
clusterService.spawnForNode(name), schemaManager))
+                    .collect(Collectors.toMap(TestNode::name, 
Function.identity()));
+
+            return new TestCluster(nodes);
+        }
+
+    }
+
+    private static class TableBuilderImpl extends 
AbstractTableBuilderImpl<TableBuilder> implements TableBuilder {
+        /** {@inheritDoc} */
+        @Override
+        public TestTable build() {
+            return new TestTable(
+                    new TableDescriptorImpl(columns, distribution), name, 
dataProviders, size
+            );
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        protected TableBuilder self() {
+            return this;
+        }
+    }
+
+    private static class ClusterTableBuilderImpl extends 
AbstractTableBuilderImpl<ClusterTableBuilder> implements ClusterTableBuilder {
+        private final ClusterBuilderImpl parent;
+
+        private ClusterTableBuilderImpl(ClusterBuilderImpl parent) {
+            this.parent = parent;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        protected ClusterTableBuilder self() {
+            return this;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ClusterBuilder end() {
+            parent.tables.add(new TestTable(
+                    new TableDescriptorImpl(columns, distribution), name, 
dataProviders, size
+            ));
+
+            return parent;
+        }
+    }
+
+    private abstract static class AbstractTableBuilderImpl<ChildT> implements 
TableBuilderBase<ChildT> {
+        protected final List<ColumnDescriptor> columns = new ArrayList<>();
+        protected final Map<String, DataProvider<?>> dataProviders = new 
HashMap<>();
+
+        protected String name;
+        protected IgniteDistribution distribution;
+        protected int size = 100_000;
+
+        protected abstract ChildT self();
+
+        /** {@inheritDoc} */
+        @Override
+        public ChildT name(String name) {
+            this.name = name;
+
+            return self();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ChildT distribution(IgniteDistribution distribution) {
+            this.distribution = distribution;
+
+            return self();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ChildT addColumn(String name, NativeType type) {
+            columns.add(new ColumnDescriptorImpl(
+                    name, false, true, columns.size(), columns.size(), type, 
DefaultValueStrategy.DEFAULT_NULL, null
+            ));
+
+            return self();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ChildT addDataProvider(String targetNode, DataProvider<?> 
dataProvider) {

Review Comment:
   > so, we can have different provider per node? is it useful ?
   
   I believe it is very useful. As a framework, it should be flexible enough to 
give an ability to configure the test cluster in the way it will be configured 
in real life (assume affinity distribution or data skews)
   
   > probably we need additional method without targetNode used for all nodes 
by default ?
   
   I added `ClusterTableBuilder#defaultDataProvider` to cover this. Please take 
a look



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to