/*
 * 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.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteJdbcThinDriver;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.cache.query.ContinuousQuery;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.ScanQuery;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.SqlConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum;
import org.apache.ignite.internal.commandline.CommandList;
import org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg;
import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate;
import org.apache.ignite.internal.metric.SystemViewSelfTest.TestRunnable;
import org.apache.ignite.internal.metric.SystemViewSelfTest.TestTransformer;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
import org.apache.ignite.internal.processors.cache.metric.SqlViewExporterSpiTest.TestAffinityFunction;
import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage;
import org.apache.ignite.internal.processors.service.DummyService;
import org.apache.ignite.internal.util.StripedExecutor;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.systemview.VisorSystemViewTask;
import org.apache.ignite.services.ServiceConfiguration;
import org.apache.ignite.spi.systemview.view.SystemView;
import org.apache.ignite.spi.systemview.view.SystemViewRowAttributeWalker.AttributeVisitor;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.transactions.Transaction;
import org.junit.Test;

import static java.lang.Integer.MAX_VALUE;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.regex.Pattern.quote;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cluster.ClusterState.ACTIVE;
import static org.apache.ignite.cluster.ClusterState.INACTIVE;
import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS;
import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
import static org.apache.ignite.internal.commandline.CommandList.SYSTEM_VIEW;
import static org.apache.ignite.internal.commandline.systemview.SystemViewCommand.COLUMN_SEPARATOR;
import static org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.NODE_ID;
import static org.apache.ignite.internal.managers.systemview.GridSystemViewManager.STREAM_POOL_QUEUE_VIEW;
import static org.apache.ignite.internal.managers.systemview.GridSystemViewManager.SYS_POOL_QUEUE_VIEW;
import static org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW;
import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_PREDICATE;
import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_TRANSFORMER;
import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW;
import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHE_GRPS_VIEW;
import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW;
import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.PART_STATES_VIEW;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId;
import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW;
import static org.apache.ignite.internal.processors.cache.index.AbstractSchemaSelfTest.queryProcessor;
import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.METASTORE_VIEW;
import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.DATA_REGION_PAGE_LIST_VIEW;
import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST;
import static org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.CQ_SYS_VIEW;
import static org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl.DISTRIBUTED_METASTORE_VIEW;
import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.toSqlName;
import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_VIEW;
import static org.apache.ignite.internal.processors.query.QueryUtils.DFLT_SCHEMA;
import static org.apache.ignite.internal.processors.query.QueryUtils.SCHEMA_SYS;
import static org.apache.ignite.internal.processors.query.h2.SchemaManager.SQL_SCHEMA_VIEW;
import static org.apache.ignite.internal.processors.query.h2.SchemaManager.SQL_TBLS_VIEW;
import static org.apache.ignite.internal.processors.query.h2.SchemaManager.SQL_TBL_COLS_VIEW;
import static org.apache.ignite.internal.processors.query.h2.SchemaManager.SQL_VIEWS_VIEW;
import static org.apache.ignite.internal.processors.query.h2.SchemaManager.SQL_VIEW_COLS_VIEW;
import static org.apache.ignite.internal.processors.service.IgniteServiceProcessor.SVCS_VIEW;
import static org.apache.ignite.internal.processors.task.GridTaskProcessor.TASKS_VIEW;
import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe;
import static org.apache.ignite.testframework.GridTestUtils.assertContains;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;

/** Tests output of {@link CommandList#SYSTEM_VIEW} command. */
public class SystemViewCommandTest extends GridCommandHandlerClusterByClassAbstractTest {
    /** Command line argument for printing content of a system view. */
    private static final String CMD_SYS_VIEW = SYSTEM_VIEW.text();

    /** Latch that is used to unblock all compute jobs. */
    private static final CountDownLatch COMPUTE_JOB_UNBLOCK_LATCH = new CountDownLatch(1);

    /** Latch that indicates number of compute jobs to be blocked.*/
    private static final CountDownLatch COMPUTE_JOB_BLOCK_LATCH = new CountDownLatch(5);

    /** Name of the test data region. */
    private static final String DATA_REGION_NAME = "in-memory";

    /** Test node with 0 index. */
    private IgniteEx ignite0;

    /** Test node with 1 index. */
    private IgniteEx ignite1;

    /** {@inheritDoc} */
    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);

        cfg.setDataStorageConfiguration(new DataStorageConfiguration()
            .setDataRegionConfigurations(new DataRegionConfiguration()
                .setName(DATA_REGION_NAME)
                .setMaxSize(100L * 1024 * 1024))
            .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
                .setPersistenceEnabled(true)));

        return cfg;
    }

    /** {@inheritDoc} */
    @Override protected void beforeTest() throws Exception {
        super.beforeTest();

        injectTestSystemOut();

        autoConfirmation = false;

        ignite0 = ignite(0);
        ignite1 = ignite(1);
    }

    /** Tests command error output in case of mandatory system view name is omitted. */
    @Test
    public void testSystemViewNameMissedFailure() {
        assertContains(log, executeCommand(EXIT_CODE_INVALID_ARGUMENTS, CMD_SYS_VIEW),
            "The name of the system view for which its content should be printed is expected.");
    }

    /** Tests command error output in case value of {@link SystemViewCommandArg#NODE_ID} argument is omitted. */
    @Test
    public void testNodeIdMissedFailure() {
        assertContains(log, executeCommand(EXIT_CODE_INVALID_ARGUMENTS, CMD_SYS_VIEW, SVCS_VIEW, NODE_ID.argName()),
            "ID of the node from which system view content should be obtained is expected.");
    }

    /** Tests command error output in case value of {@link SystemViewCommandArg#NODE_ID} argument is invalid.*/
    @Test
    public void testInvalidNodeIdFailure() {
        assertContains(log,
            executeCommand(EXIT_CODE_INVALID_ARGUMENTS, CMD_SYS_VIEW, SVCS_VIEW, NODE_ID.argName(), "invalid_node_id"),
            "Failed to parse " + NODE_ID.argName() +
                " command argument. String representation of \"java.util.UUID\" is exepected." +
                " For example: 123e4567-e89b-42d3-a456-556642440000"
        );
    }

    /** Tests command error output in case multiple system view names are specified. */
    @Test
    public void testMultipleSystemViewNamesFailure() {
        assertContains(log,
            executeCommand(EXIT_CODE_INVALID_ARGUMENTS, CMD_SYS_VIEW, SVCS_VIEW, CACHE_GRP_PAGE_LIST_VIEW),
            "Multiple system view names are not supported.");
    }

    /**
     * Tests command error output in case {@link SystemViewCommandArg#NODE_ID} argument value refers to nonexistent
     * node.
     */
    @Test
    public void testNonExistentNodeIdFailure() {
        String incorrectNodeId = UUID.randomUUID().toString();

        assertContains(log,
            executeCommand(EXIT_CODE_INVALID_ARGUMENTS, CMD_SYS_VIEW, "--node-id", incorrectNodeId, CACHES_VIEW),
            "Failed to perform operation.\nNode with id=" + incorrectNodeId + " not found");
    }

    /** Tests command output in case nonexistent system view names is specified. */
    @Test
    public void testNonExistentSystemView() {
        assertContains(log, executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, "non_existent_system_view"),
            "No system view with specified name was found [name=non_existent_system_view]");
    }

    /** */
    @Test
    public void testCachesView() {
        Set<String> cacheNames = new HashSet<>(asList("cache-1", "cache-2"));

        cacheNames.forEach(cacheName -> ignite0.createCache(cacheName));

        List<List<String>> cachesView = systemView(ignite0, CACHES_VIEW);

        assertEquals(ignite0.context().cache().cacheDescriptors().size(), cachesView.size());

        cachesView.forEach(row -> cacheNames.remove(row.get(0)));

        assertTrue(cacheNames.isEmpty());
    }

    /** */
    @Test
    public void testCacheGroupsView() {
        Set<String> grpNames = new HashSet<>(asList("grp-1", "grp-2"));

        for (String grpName : grpNames)
            ignite0.createCache(new CacheConfiguration<>("cache-" + grpName).setGroupName(grpName));

        List<List<String>> cacheGrpsView = systemView(ignite0, CACHE_GRPS_VIEW);

        assertEquals(ignite0.context().cache().cacheGroupDescriptors().size(), cacheGrpsView.size());

        cacheGrpsView.forEach(row -> grpNames.remove(row.get(0)));

        assertTrue(grpNames.toString(), grpNames.isEmpty());
    }

    /** */
    @Test
    public void testComputeBroadcast() throws Exception {
        long tasksCnt = COMPUTE_JOB_BLOCK_LATCH.getCount();

        try {
            for (int i = 0; i < tasksCnt; i++) {
                ignite0.compute().broadcastAsync(() -> {
                    try {
                        COMPUTE_JOB_BLOCK_LATCH.countDown();
                        COMPUTE_JOB_UNBLOCK_LATCH.await();
                    }
                    catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }

            COMPUTE_JOB_BLOCK_LATCH.await();

            List<List<String>> tasksView = systemView(ignite0, TASKS_VIEW).stream()
                .filter(row -> !VisorSystemViewTask.class.getName().equals(row.get(3)))
                .collect(Collectors.toList());

            assertEquals(tasksCnt, tasksView.size());

            tasksView.forEach(row -> {
                assertEquals("false", row.get(10)); //internal
                assertEquals("null", row.get(6)); // affinityCacheName
                assertEquals("-1", row.get(5)); // affinityPartitionId
                assertTrue(row.get(4).startsWith(getClass().getName())); // taskClassName
                assertTrue(row.get(3).startsWith(getClass().getName())); // taskName
                assertEquals(ignite0.localNode().id().toString(), row.get(2)); // taskNodeId
                assertEquals("0", row.get(12)); // userVersion
            });
        }
        finally {
            COMPUTE_JOB_UNBLOCK_LATCH.countDown();
        }
    }

    /** */
    @Test
    public void testServices() {
        ServiceConfiguration srvcCfg = new ServiceConfiguration();

        srvcCfg.setName("service");
        srvcCfg.setMaxPerNodeCount(1);
        srvcCfg.setService(new DummyService());

        ignite0.services().deploy(srvcCfg);

        List<List<String>> srvsView = systemView(ignite0, SVCS_VIEW);

        assertEquals(1, srvsView.size());

        List<String> sysView = srvsView.get(0);

        assertEquals(srvcCfg.getName(), sysView.get(1)); // name
        assertEquals(DummyService.class.getName(), sysView.get(2)); // serviceClass
        assertEquals(Integer.toString(srvcCfg.getMaxPerNodeCount()), sysView.get(6)); // maxPerNodeCount
    }

    /** */
    @Test
    public void testClientsConnections() throws Exception {
        String host = ignite0.configuration().getClientConnectorConfiguration().getHost();

        if (host == null)
            host = ignite0.configuration().getLocalHost();

        int port = ignite0.configuration().getClientConnectorConfiguration().getPort();

        try (
            IgniteClient ignored1 = Ignition.startClient(new ClientConfiguration().setAddresses(host + ":" + port));
            Connection ignored2 = new IgniteJdbcThinDriver().connect("jdbc:ignite:thin://" + host, new Properties())
        ) {
            assertEquals(2, systemView(ignite0, CLI_CONN_VIEW).size());
        }
    }

    /** */
    @Test
    public void testTransactions() throws Exception {
        IgniteCache<Integer, Integer> cache = ignite0.createCache(
            new CacheConfiguration<Integer, Integer>("test-cache").setAtomicityMode(TRANSACTIONAL));

        assertTrue(systemView(ignite0, TXS_MON_LIST).isEmpty());

        CountDownLatch txBlockLatch = new CountDownLatch(10);
        CountDownLatch txUnblockLatch = new CountDownLatch(1);

        try {
            AtomicInteger cntr = new AtomicInteger();

            GridTestUtils.runMultiThreadedAsync(() -> {
                try (
                    Transaction ignored = ignite0.transactions().withLabel("test")
                        .txStart(PESSIMISTIC, REPEATABLE_READ)
                ) {
                    cache.put(cntr.incrementAndGet(), cntr.incrementAndGet());
                    cache.put(cntr.incrementAndGet(), cntr.incrementAndGet());

                    txBlockLatch.countDown();
                    txUnblockLatch.await();
                }
                catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }, 5, "sys-view-cmd-tx-test-1");

            GridTestUtils.runMultiThreadedAsync(() -> {
                try (Transaction ignored = ignite0.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
                    cache.put(cntr.incrementAndGet(), cntr.incrementAndGet());
                    cache.put(cntr.incrementAndGet(), cntr.incrementAndGet());

                    txBlockLatch.countDown();
                    txUnblockLatch.await();
                }
                catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }, 5, "sys-view-cmd-tx-test-2");

            txBlockLatch.await(getTestTimeout(), MILLISECONDS);

            List<List<String>> txsView = systemView(ignite0, TXS_MON_LIST);

            assertEquals(10, txsView.size());
        }
        finally {
            txUnblockLatch.countDown();
        }

        assertTrue(waitForCondition(() -> systemView(ignite0, TXS_MON_LIST).isEmpty(), getTestTimeout()));
    }

    /** */
    @Test
    public void testSchemas() throws Exception {
        try (
            IgniteEx g = startGrid(getConfiguration(getTestIgniteInstanceName(3))
                .setSqlConfiguration(new SqlConfiguration().setSqlSchemas("MY_SCHEMA", "ANOTHER_SCHEMA")))
        ) {
            Set<String> schemaNames = new HashSet<>();

            HashSet<String> expSchemas = new HashSet<>(asList("MY_SCHEMA", "ANOTHER_SCHEMA", "SYS", "PUBLIC"));

            List<List<String>> sqlSchemaView = systemView(g, SQL_SCHEMA_VIEW);

            sqlSchemaView.forEach(row -> schemaNames.add(row.get(0))); // name

            assertEquals(schemaNames, expSchemas);
        }
    }

    /** */
    @Test
    public void testViews() {
        Set<String> expViewNames = new HashSet<>(asList(
            "METRICS",
            "VIEWS",
            "SERVICES",
            "CACHE_GROUPS",
            "CACHES",
            "TASKS",
            "JOBS",
            "SQL_QUERIES_HISTORY",
            "NODES",
            "SCHEMAS",
            "NODE_METRICS",
            "BASELINE_NODES",
            "BASELINE_NODE_ATTRIBUTES",
            "INDEXES",
            "LOCAL_CACHE_GROUPS_IO",
            "SQL_QUERIES",
            "SCAN_QUERIES",
            "NODE_ATTRIBUTES",
            "TABLES",
            "CLIENT_CONNECTIONS",
            "TABLE_COLUMNS",
            "VIEW_COLUMNS",
            "TRANSACTIONS",
            "CONTINUOUS_QUERIES",
            "STRIPED_THREADPOOL_QUEUE",
            "DATASTREAM_THREADPOOL_QUEUE",
            "DATA_REGION_PAGE_LISTS",
            "CACHE_GROUP_PAGE_LISTS",
            "PARTITION_STATES",
            "BINARY_METADATA",
            "METASTORAGE",
            "DISTRIBUTED_METASTORAGE",
            "STATISTICS_CONFIGURATION",
            "STATISTICS_PARTITION_DATA",
            "STATISTICS_LOCAL_DATA"
        ));

        Set<String> viewNames = new HashSet<>();

        List<List<String>> sqlViewsView = systemView(ignite0, SQL_VIEWS_VIEW);

        sqlViewsView.forEach(row -> viewNames.add(row.get(0))); // name

        assertEquals(expViewNames, viewNames);
    }

    /** */
    @Test
    public void testTable() {
        assertTrue(systemView(ignite0, SQL_TBLS_VIEW).isEmpty());

        executeSql(ignite0, "CREATE TABLE T1(ID LONG PRIMARY KEY, NAME VARCHAR)");

        List<List<String>> sqlTablesView = systemView(ignite0, SQL_TBLS_VIEW);

        assertEquals(1, sqlTablesView.size());

        List<String> row = sqlTablesView.get(0);

        assertEquals(Integer.toString(cacheId("SQL_PUBLIC_T1")), row.get(0)); // CACHE_GROUP_ID
        assertEquals("SQL_PUBLIC_T1", row.get(1)); // CACHE_GROUP_NAME
        assertEquals(Integer.toString(cacheId("SQL_PUBLIC_T1")), row.get(2)); // CACHE_ID
        assertEquals("SQL_PUBLIC_T1", row.get(3)); // CACHE_NAME
        assertEquals(DFLT_SCHEMA, row.get(4)); // SCHEMA_NAME
        assertEquals("T1", row.get(5)); // TABLE_NAME
        assertEquals("null", row.get(6)); // AFFINITY_KEY_COLUMN
        assertEquals("ID", row.get(7)); // KEY_ALIAS
        assertEquals("null", row.get(8)); // VALUE_ALIAS
        assertEquals("java.lang.Long", row.get(9)); // KEY_TYPE_NAME
        assertFalse("null".equals(row.get(10))); // VALUE_TYPE_NAME

        executeSql(ignite0, "CREATE TABLE T2(ID LONG PRIMARY KEY, NAME VARCHAR)");

        assertEquals(2, systemView(ignite0, SQL_TBLS_VIEW).size());

        executeSql(ignite0, "DROP TABLE T1");
        executeSql(ignite0, "DROP TABLE T2");

        assertTrue(systemView(ignite0, SQL_TBLS_VIEW).isEmpty());
    }

    /** */
    @Test
    public void testTableColumns() {
        assertTrue(systemView(ignite0, SQL_TBL_COLS_VIEW).isEmpty());

        executeSql(ignite0, "CREATE TABLE T1(ID LONG PRIMARY KEY, NAME VARCHAR(40))");

        Set<?> actCols = systemView(ignite0, SQL_TBL_COLS_VIEW).stream()
            .map(row -> row.get(0)) // columnName
            .collect(Collectors.toSet());

        assertEquals(new HashSet<>(asList("ID", "NAME", "_KEY", "_VAL")), actCols);

        executeSql(ignite0, "CREATE TABLE T2(ID LONG PRIMARY KEY, NAME VARCHAR(50))");

        Set<List<String>> expSqlTableColumnsView = new HashSet<>(asList(
            asList("ID", "T1", "PUBLIC", "false", "false", "null", "true", "true", "-1", "-1", Long.class.getName()),
            asList("NAME", "T1", "PUBLIC", "false", "false", "null", "true", "false", "40", "-1", String.class.getName()),
            asList("_KEY", "T1", "PUBLIC", "true", "false", "null", "false", "true", "-1", "-1", "null"),
            asList("_VAL", "T1", "PUBLIC", "false", "false", "null", "true", "false", "-1", "-1", "null"),
            asList("ID", "T2", "PUBLIC", "false", "false", "null", "true", "true", "-1", "-1", Long.class.getName()),
            asList("NAME", "T2", "PUBLIC", "false", "false", "null", "true", "false", "50", "-1", String.class.getName()),
            asList("_KEY", "T2", "PUBLIC", "true", "false", "null", "false", "true", "-1", "-1", "null"),
            asList("_VAL", "T2", "PUBLIC", "false", "false", "null", "true", "false", "-1", "-1", "null")
        ));

        Set<List<String>> sqlTableColumnsView = new HashSet<>(systemView(ignite0, SQL_TBL_COLS_VIEW));

        assertEquals(expSqlTableColumnsView, sqlTableColumnsView);

        executeSql(ignite0, "DROP TABLE T1");
        executeSql(ignite0, "DROP TABLE T2");

        assertTrue(systemView(ignite0, SQL_TBL_COLS_VIEW).isEmpty());
    }

    /** */
    @Test
    public void testViewColumns() {
        Set<List<String>> expsqlViewColumnsView = new HashSet<>(asList(
            asList("CONNECTION_ID", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", "19", "0", Long.class.getName()),
            asList("LOCAL_ADDRESS", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", Integer.toString(MAX_VALUE), "0",
                String.class.getName()),
            asList("REMOTE_ADDRESS", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", Integer.toString(MAX_VALUE), "0",
                String.class.getName()),
            asList("TYPE", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", Integer.toString(MAX_VALUE), "0",
                String.class.getName()),
            asList("USER", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", Integer.toString(MAX_VALUE), "0",
                String.class.getName()),
            asList("VERSION", "CLIENT_CONNECTIONS", SCHEMA_SYS, "null", "true", Integer.toString(MAX_VALUE), "0",
                String.class.getName())
        ));

        Set<List<String>> sqlViewColumnsView = systemView(ignite0, SQL_VIEW_COLS_VIEW).stream()
            .filter(row -> "CLIENT_CONNECTIONS".equals(row.get(1))) // viewName
            .collect(Collectors.toSet());

        assertEquals(expsqlViewColumnsView, sqlViewColumnsView);
    }

    /** */
    @Test
    public void testContinuousQuery() throws Exception {
        IgniteCache<Integer, Integer> cache = ignite0.createCache("test-cache");

        assertTrue(systemView(ignite0, CQ_SYS_VIEW).isEmpty());
        assertTrue(systemView(ignite1, CQ_SYS_VIEW).isEmpty());

        try (QueryCursor<?> ignored = cache.query(new ContinuousQuery<>()
            .setInitialQuery(new ScanQuery<>())
            .setPageSize(100)
            .setTimeInterval(1000)
            .setLocalListener(evts -> {
                // No-op.
            })
            .setRemoteFilterFactory(() -> evt -> true)
        )) {
            for (int i = 0; i < 100; i++)
                cache.put(i, i);

            checkContinuouQueryView(ignite0, true);
            checkContinuouQueryView(ignite1, false);
        }

        assertTrue(systemView(ignite0, CQ_SYS_VIEW).isEmpty());
        assertTrue(waitForCondition(() -> systemView(ignite1, CQ_SYS_VIEW).isEmpty(), getTestTimeout()));
    }

    /** */
    private void checkContinuouQueryView(IgniteEx node, boolean loc) {
        List<List<String>> cqSysView = systemView(node, CQ_SYS_VIEW);

        assertEquals(1, cqSysView.size());

        List<String> row = cqSysView.get(0);

        assertEquals("test-cache", row.get(0)); //cacheName
        assertEquals("100", row.get(7)); // bufferSize
        assertEquals("1000", row.get(9)); // interval
        assertEquals(ignite0.localNode().id().toString(), row.get(14)); // nodeId

        if (loc)
            assertTrue(row.get(1).startsWith(getClass().getName())); // localListener
        else
            assertEquals("null", row.get(1)); // localListener

        assertTrue(row.get(2).startsWith(getClass().getName())); // remoteFilter
        assertEquals("null", row.get(4)); // localTransformedListener
        assertEquals("null", row.get(3)); // remoteTransformer
    }

    /** */
    @Test
    public void testLocalScanQuery() throws Exception {
        IgniteCache<Integer, Integer> cache1 = ignite0.createCache(
            new CacheConfiguration<Integer, Integer>("cache1").setGroupName("group1"));

        int part = ignite0.affinity("cache1").primaryPartitions(ignite0.localNode())[0];

        List<Integer> partKeys = partitionKeys(cache1, part, 11, 0);

        partKeys.forEach(key -> cache1.put(key, key));

        assertTrue(systemView(ignite0, SCAN_QRY_SYS_VIEW).isEmpty());

        try (
            QueryCursor<Integer> qryRes1 = cache1.query(
                new ScanQuery<Integer, Integer>()
                    .setFilter(new TestPredicate())
                    .setLocal(true)
                    .setPartition(part)
                    .setPageSize(10),
                new TestTransformer())
        ) {
            assertTrue(qryRes1.iterator().hasNext());

            assertTrue(waitForCondition(() -> !systemView(ignite0, SCAN_QRY_SYS_VIEW).isEmpty(), getTestTimeout()));

            List<String> view = systemView(ignite0, SCAN_QRY_SYS_VIEW).get(0);

            assertEquals(ignite0.localNode().id().toString(), view.get(0)); // originNodeId
            assertEquals("0", view.get(1)); // queryId
            assertEquals("cache1", view.get(2)); // cacheName
            assertEquals(Integer.toString(cacheId("cache1")), view.get(3)); // cacheId
            assertEquals(Integer.toString(cacheGroupId("cache1", "group1")), view.get(4)); // cacheGroupId
            assertEquals("group1", view.get(5)); // cacheGroupName
            assertTrue(Long.parseLong(view.get(6)) <= System.currentTimeMillis()); // startTime
            assertTrue(Long.parseLong(view.get(7)) >= 0); // duration
            assertFalse(Boolean.parseBoolean(view.get(8))); // canceled
            assertEquals(TEST_PREDICATE, view.get(9)); // filter
            assertTrue(Boolean.parseBoolean(view.get(11))); // local
            assertEquals(part, Integer.parseInt(view.get(13))); // partition
            assertEquals(toStringSafe(ignite0.context().discovery().topologyVersionEx()), view.get(16)); // topology
            assertEquals(TEST_TRANSFORMER, view.get(17)); // transformer
            assertFalse(Boolean.parseBoolean(view.get(10))); // keepBinary
            assertEquals("null", view.get(14)); // subjectId
            assertEquals("null", view.get(15)); // taskName
        }

        assertTrue(waitForCondition(() -> systemView(ignite0, SCAN_QRY_SYS_VIEW).isEmpty(), getTestTimeout()));
    }

    /** */
    @Test
    public void testScanQuery() throws Exception {
        try (
            IgniteEx client1 = startClientGrid("client-1");
            IgniteEx client2 = startClientGrid("client-2")
        ) {
            IgniteCache<Integer, Integer> cache1 = client1.createCache(
                new CacheConfiguration<Integer, Integer>("cache1").setGroupName("group1"));

            IgniteCache<Integer, Integer> cache2 = client2.createCache("cache2");

            for (int i = 0; i < 100; i++) {
                cache1.put(i, i);
                cache2.put(i, i);
            }

            assertTrue(systemView(ignite0, SCAN_QRY_SYS_VIEW).isEmpty());
            assertTrue(systemView(ignite1, SCAN_QRY_SYS_VIEW).isEmpty());

            try (
                QueryCursor<Integer> qryRes1 = cache1.query(
                    new ScanQuery<Integer, Integer>()
                        .setFilter(new TestPredicate())
                        .setPageSize(10),
                    new TestTransformer());

                QueryCursor<?> qryRes2 = cache2.withKeepBinary().query(new ScanQuery<>().setPageSize(20))
            ) {
                assertTrue(qryRes1.iterator().hasNext());
                assertTrue(qryRes2.iterator().hasNext());

                checkScanQueryView(client1, client2, ignite0);
                checkScanQueryView(client1, client2, ignite1);
            }

            assertTrue(waitForCondition(() ->
                systemView(ignite0, SCAN_QRY_SYS_VIEW).isEmpty() && systemView(ignite1, SCAN_QRY_SYS_VIEW).isEmpty(),
                getTestTimeout()));
        }
    }

    /** */
    private void checkScanQueryView(IgniteEx client1, IgniteEx client2, IgniteEx node) throws Exception {
        assertTrue(waitForCondition(() -> systemView(ignite0, SCAN_QRY_SYS_VIEW).size() > 1, getTestTimeout()));

        Consumer<List<String>> cache1checker = view -> {
            assertEquals(client1.localNode().id().toString(), view.get(0));
            assertTrue(Long.parseLong(view.get(1)) != 0);
            assertEquals("cache1", view.get(2));
            assertEquals(Integer.toString(cacheId("cache1")), view.get(3));
            assertEquals(Integer.toString(cacheGroupId("cache1", "group1")), view.get(4));
            assertEquals("group1", view.get(5));
            assertTrue(Long.parseLong(view.get(6)) <= System.currentTimeMillis());
            assertTrue(Long.parseLong(view.get(7)) >= 0);
            assertFalse(Boolean.parseBoolean(view.get(8)));
            assertEquals(TEST_PREDICATE, view.get(9));
            assertFalse(Boolean.parseBoolean(view.get(11)));
            assertEquals("-1", view.get(13));
            assertEquals(toStringSafe(client1.context().discovery().topologyVersionEx()), view.get(16));
            assertEquals(TEST_TRANSFORMER, view.get(17));
            assertFalse(Boolean.parseBoolean(view.get(10)));
            assertEquals("null", view.get(14));
            assertEquals("null", view.get(15));
            assertEquals("10", view.get(12));
        };

        Consumer<List<String>> cache2checker = view -> {
            assertEquals(client2.localNode().id().toString(), view.get(0));
            assertTrue(Long.parseLong(view.get(1)) != 0);
            assertEquals("cache2", view.get(2));
            assertEquals(Integer.toString(cacheId("cache2")), view.get(3));
            assertEquals(Integer.toString(cacheGroupId("cache2", null)), view.get(4));
            assertEquals("cache2", view.get(5));
            assertTrue(Long.parseLong(view.get(6)) <= System.currentTimeMillis());
            assertTrue(Long.parseLong(view.get(7)) >= 0);
            assertFalse(Boolean.parseBoolean(view.get(8)));
            assertEquals("null", view.get(9));
            assertFalse(Boolean.parseBoolean(view.get(11)));
            assertEquals("-1", view.get(13));
            assertEquals(toStringSafe(client2.context().discovery().topologyVersionEx()), view.get(16));
            assertEquals("null", view.get(17));
            assertTrue(Boolean.parseBoolean(view.get(10)));
            assertEquals("null", view.get(14));
            assertEquals("null", view.get(15));
            assertEquals("20", view.get(12));
        };

        boolean found1 = false;
        boolean found2 = false;

        for (List<String> row : systemView(node, SCAN_QRY_SYS_VIEW)) {
            if ("cache2".equals(row.get(2))) {
                cache2checker.accept(row);
                found1 = true;
            }
            else {
                cache1checker.accept(row);
                found2 = true;
            }
        }

        assertTrue(found1 && found2);
    }

    /** */
    @Test
    public void testStripedExecutor() throws Exception {
        checkStripeExecutorView(ignite0.context().pools().getStripedExecutorService(),
            SYS_POOL_QUEUE_VIEW,
            "sys");
    }

    /** */
    @Test
    public void testStreamerExecutor() throws Exception {
        checkStripeExecutorView(ignite0.context().pools().getDataStreamerExecutorService(),
            STREAM_POOL_QUEUE_VIEW,
            "data-streamer");
    }

    /**
     * Checks striped executor system view.
     *
     * @param execSvc Striped executor.
     * @param view System view name.
     * @param poolName Executor name.
     */
    private void checkStripeExecutorView(StripedExecutor execSvc, String view, String poolName) throws Exception {
        CountDownLatch latch = new CountDownLatch(1);

        execSvc.execute(0, new TestRunnable(latch, 0));
        execSvc.execute(0, new TestRunnable(latch, 1));
        execSvc.execute(1, new TestRunnable(latch, 2));
        execSvc.execute(1, new TestRunnable(latch, 3));

        try {
            assertTrue(waitForCondition(() -> systemView(ignite0, view).size() == 2, getTestTimeout()));

            List<List<String>> stripedQueue = systemView(ignite0, view);

            List<String> row0 = stripedQueue.get(0);

            assertEquals("0", row0.get(0));
            assertEquals(TestRunnable.class.getSimpleName() + '1', row0.get(1));
            assertEquals(poolName + "-stripe-0", row0.get(2));
            assertEquals(TestRunnable.class.getName(), row0.get(3));

            List<String> row1 = stripedQueue.get(1);

            assertEquals("1", row1.get(0));
            assertEquals(TestRunnable.class.getSimpleName() + '3', row1.get(1));
            assertEquals(poolName + "-stripe-1", row1.get(2));
            assertEquals(TestRunnable.class.getName(), row1.get(3));
        }
        finally {
            latch.countDown();
        }
    }

    /** */
    @Test
    public void testPagesList() throws Exception {
        String cacheName = "cacheFL";

        IgniteCache<Integer, byte[]> cache = ignite0.getOrCreateCache(new CacheConfiguration<Integer, byte[]>()
            .setName(cacheName)
            .setAffinity(new RendezvousAffinityFunction()
                .setPartitions(1)));

        GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)ignite0.context().cache().context()
            .database();

        int pageSize = dbMgr.pageSize();

        try {
            dbMgr.enableCheckpoints(false).get();

            int key = 0;

            // Fill up different free-list buckets.
            for (int j = 0; j < pageSize / 2; j++)
                cache.put(key++, new byte[j + 1]);

            // Put some pages to one bucket to overflow pages cache.
            for (int j = 0; j < 1000; j++)
                cache.put(key++, new byte[pageSize / 2]);

            List<List<String>> cacheGrpView = systemView(ignite0, CACHE_GRP_PAGE_LIST_VIEW);

            List<List<String>> dataRegionView = systemView(ignite0, DATA_REGION_PAGE_LIST_VIEW);

            String cacheId = Integer.toString(cacheId(cacheName));

            // Test filtering by 3 columns.
            assertFalse(cacheGrpView.stream().noneMatch(row ->
                cacheId.equals(row.get(0)) &&
                "0".equals(row.get(1)) &&
                "0".equals(row.get(3))));

            // Test filtering with invalid cache group id.
            assertTrue(cacheGrpView.stream().noneMatch(row -> "-1".equals(row.get(0))));

            // Test filtering with invalid partition id.
            assertTrue(cacheGrpView.stream().noneMatch(row -> "-1".equals(row.get(1))));

            // Test filtering with invalid bucket number.
            assertTrue(cacheGrpView.stream().noneMatch(row -> "-1".equals(row.get(3))));

            assertFalse(cacheGrpView.stream().noneMatch(row ->
                Integer.parseInt(row.get(4)) > 0 && cacheId.equals(row.get(0))));

            assertFalse(cacheGrpView.stream().noneMatch(row ->
                Integer.parseInt(row.get(5)) > 0 && cacheId.equals(row.get(0))));

            assertFalse(cacheGrpView.stream().noneMatch(row ->
                Integer.parseInt(row.get(6)) > 0 && cacheId.equals(row.get(0))));

            assertFalse(dataRegionView.stream().noneMatch(row -> row.get(0).startsWith(DATA_REGION_NAME)));

            assertTrue(dataRegionView.stream().noneMatch(row ->
                row.get(0).startsWith(DATA_REGION_NAME) && Integer.parseInt(row.get(4)) > 0));
        }
        finally {
            dbMgr.enableCheckpoints(true).get();
        }

        ignite0.cluster().state(INACTIVE);

        ignite0.cluster().state(ACTIVE);

        IgniteCache<Integer, Integer> cacheInMemory = ignite0.getOrCreateCache(
            new CacheConfiguration<Integer, Integer>()
                .setName("cacheFLInMemory")
                .setDataRegionName(DATA_REGION_NAME));

        cacheInMemory.put(0, 0);

        // After activation/deactivation new view for data region pages lists should be created, check that new view
        // correctly reflects changes in free-lists.
        assertTrue(systemView(ignite0, DATA_REGION_PAGE_LIST_VIEW).stream().noneMatch(row ->
            row.get(0).startsWith(DATA_REGION_NAME) && Integer.parseInt(row.get(4)) > 0));
    }

    /** */
    @Test
    public void testPartitionStates() throws Exception {
        String nodeName0 = getTestIgniteInstanceName(0);
        String nodeName1 = getTestIgniteInstanceName(1);
        String nodeName2 = getTestIgniteInstanceName(2);

        IgniteCache<Integer, Integer> cache1 = ignite0.createCache(new CacheConfiguration<Integer, Integer>()
            .setName("cache1")
            .setCacheMode(CacheMode.PARTITIONED)
            .setAffinity(new TestAffinityFunction(new String[][] {{nodeName0, nodeName1}, {nodeName1, nodeName2},
                {nodeName2, nodeName0}})));

        IgniteCache<Integer, Integer> cache2 = ignite0.createCache(new CacheConfiguration<Integer, Integer>()
            .setName("cache2")
            .setCacheMode(CacheMode.PARTITIONED)
            .setAffinity(new TestAffinityFunction(new String[][] {{nodeName0, nodeName1, nodeName2}, {nodeName1}})));

        for (int i = 0; i < 100; i++) {
            cache1.put(i, i);
            cache2.put(i, i);
        }

        try (IgniteEx ignite2 = startGrid(nodeName2)) {
            ignite2.rebalanceEnabled(false);

            ignite0.cluster().setBaselineTopology(ignite0.cluster().topologyVersion());

            String nodeId0 = ignite0.cluster().localNode().id().toString();
            String nodeId1 = ignite(1).cluster().localNode().id().toString();
            String nodeId2 = ignite2.cluster().localNode().id().toString();

            String cacheGrpId1 = Integer.toString(ignite0.cachex("cache1").context().groupId());
            String cacheGrpId2 = Integer.toString(ignite0.cachex("cache2").context().groupId());

            String owningState = GridDhtPartitionState.OWNING.name();
            String movingState = GridDhtPartitionState.MOVING.name();

            for (int i = 0; i < 3; i++) {
                List<List<String>> partStatesView = systemView(ignite(i), PART_STATES_VIEW);

                // Check partitions for cache1.
                checkPartitionStatesView(partStatesView, owningState, true, cacheGrpId1, nodeId0, 0);
                checkPartitionStatesView(partStatesView, owningState, false, cacheGrpId1, nodeId1, 0);
                checkPartitionStatesView(partStatesView, owningState, true, cacheGrpId1, nodeId1, 1);
                checkPartitionStatesView(partStatesView, movingState, false, cacheGrpId1, nodeId2, 1);
                checkPartitionStatesView(partStatesView, owningState, true, cacheGrpId1, nodeId0, 2);
                checkPartitionStatesView(partStatesView, movingState, false, cacheGrpId1, nodeId2, 2);

                checkPartitionStatesView(partStatesView, owningState, true, cacheGrpId2, nodeId0, 0);
                checkPartitionStatesView(partStatesView, owningState, false, cacheGrpId2, nodeId1, 0);
                checkPartitionStatesView(partStatesView, movingState, false, cacheGrpId2, nodeId2, 0);
                checkPartitionStatesView(partStatesView, owningState, true, cacheGrpId2, nodeId1, 1);
            }

            AffinityTopologyVersion topVer = ignite0.context().discovery().topologyVersionEx();

            ignite2.rebalanceEnabled(true);

            // Wait until rebalance complete.
            assertTrue(waitForCondition(() ->
                ignite0.context().discovery().topologyVersionEx().compareTo(topVer) > 0, getTestTimeout()));

            for (int i = 0; i < 3; i++) {
                List<List<String>> rows = systemView(ignite(i), PART_STATES_VIEW);

                assertEquals(10, rows.stream().filter(row ->
                    (cacheGrpId1.equals(row.get(0)) || cacheGrpId2.equals(row.get(0))) && owningState.equals(row.get(3))).count());

                assertTrue(rows.stream().noneMatch(row ->
                    (cacheGrpId1.equals(row.get(0)) || cacheGrpId2.equals(row.get(0))) && movingState.equals(row.get(3))));
            }

            // Check that assignment is now changed to ideal.
            for (int i = 0; i < 3; i++) {
                List<List<String>> rows = systemView(ignite(i), PART_STATES_VIEW);

                checkPartitionStatesView(rows, owningState, false, cacheGrpId1, nodeId0, 2);
                checkPartitionStatesView(rows, owningState, true, cacheGrpId1, nodeId2, 2);
            }
        }
        finally {
            ignite0.cluster().setBaselineTopology(ignite0.cluster().topologyVersion());
        }
    }

    /**
     * Checks that partitions stated view contains row with specified parameters.
     *
     * @param partStatesView Partition states view rows.
     * @param state Partition state.
     * @param isPrimary Primary falg.
     * @param cacheGrpId Cache group id.
     * @param nodeId Node id.
     * @param partitionId partition id.
     */
    private void checkPartitionStatesView(
        List<List<String>> partStatesView,
        String state,
        boolean isPrimary,
        String cacheGrpId,
        String nodeId,
        int partitionId
    ) {
        assertEquals(1, partStatesView.stream().filter(row ->
            cacheGrpId.equals(row.get(0)) &&
                nodeId.equals(row.get(1)) &&
                Integer.toString(partitionId).equals(row.get(2)) &&
                state.equals(row.get(3)) &&
                Boolean.toString(isPrimary).equals(row.get(4))
        ).count());
    }

    /** */
    @Test
    public void testBinaryMeta() {
        IgniteCache<Integer, TestObjectAllTypes> c1 = ignite0.createCache("test-cache");
        IgniteCache<Integer, TestObjectEnum> c2 = ignite0.createCache("test-enum-cache");

        executeSql(ignite0, "CREATE TABLE T1(ID LONG PRIMARY KEY, NAME VARCHAR(40), ACCOUNT BIGINT)");
        executeSql(ignite0, "INSERT INTO T1(ID, NAME, ACCOUNT) VALUES(1, 'test', 1)");

        c1.put(1, new TestObjectAllTypes());
        c2.put(1, TestObjectEnum.A);

        List<List<String>> binaryMetaView = systemView(ignite0, BINARY_METADATA_VIEW);

        assertEquals(3, binaryMetaView.size());

        for (List<String> row : binaryMetaView) {
            if (Objects.equals(TestObjectEnum.class.getName(), row.get(1))) {
                assertTrue(Boolean.parseBoolean(row.get(6)));

                assertEquals("0", row.get(3));
            }
            else if (Objects.equals(TestObjectAllTypes.class.getName(), row.get(1))) {
                assertFalse(Boolean.parseBoolean(row.get(6)));

                Field[] fields = TestObjectAllTypes.class.getDeclaredFields();

                assertEquals(Integer.toString(fields.length), row.get(3));

                for (Field field : fields)
                    assertTrue(row.get(4).contains(field.getName()));
            }
            else {
                assertFalse(Boolean.parseBoolean(row.get(6)));

                assertEquals("2", row.get(3));

                assertTrue(row.get(4).contains("NAME"));
                assertTrue(row.get(4).contains("ACCOUNT"));
            }
        }
    }

    /** */
    @Test
    public void testMetastorage() throws Exception {
        IgniteCacheDatabaseSharedManager db = ignite0.context().cache().context().database();

        String name = "test-key";
        String val = "test-value";

        db.checkpointReadLock();

        try {
            db.metaStorage().write(name, val);
        }
        finally {
            db.checkpointReadUnlock();
        }

        assertEquals(1, systemView(ignite0, METASTORE_VIEW).stream()
            .filter(row -> name.equals(row.get(0)) && val.equals(row.get(1)))
            .count());
    }

    /** */
    @Test
    public void testDistributedMetastorage() throws Exception {
        DistributedMetaStorage dms = ignite0.context().distributedMetastorage();

        String name = "test-distributed-key";
        String val = "test-distributed-value";

        dms.write(name, val);

        assertEquals(1, systemView(ignite0, DISTRIBUTED_METASTORE_VIEW).stream()
            .filter(row -> name.equals(row.get(0)) && val.equals(row.get(1)))
            .count());

        assertTrue(waitForCondition(() -> systemView(ignite1, DISTRIBUTED_METASTORE_VIEW).stream()
                .filter(row -> name.equals(row.get(0)) && val.equals(row.get(1)))
                .count() == 1,
            getTestTimeout()));
    }

    /**
     * Execute query on given node.
     *
     * @param node Node.
     * @param sql Statement.
     */
    private List<List<?>> executeSql(Ignite node, String sql, Object... args) {
        SqlFieldsQuery qry = new SqlFieldsQuery(sql)
            .setArgs(args)
            .setSchema("PUBLIC");

        return queryProcessor(node).querySqlFields(qry, true).getAll();
    }

    /**
     * Gets system view content via control utility from specified node. Here we also check if attributes names
     * returned by the command match the real ones. And that both "SQL" and "Java" command names styles are supported.
     *
     * @param node The node to obtain system view from.
     * @param sysViewName Name of the system view which content is required.
     * @return Content of the requested system view.
     */
    private List<List<String>> systemView(IgniteEx node, String sysViewName) {
        List<String> attrNames = new ArrayList<>();

        SystemView<?> sysView = node.context().systemView().view(sysViewName);

        sysView.walker().visitAll(new AttributeVisitor() {
            @Override public <T> void accept(int idx, String name, Class<T> clazz) {
                attrNames.add(name);
            }
        });

        String nodeId = node.context().discovery().localNode().id().toString();

        List<List<String>> rows = parseSystemViewCommandOutput(
            executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, toSqlName(sysViewName), NODE_ID.argName(), nodeId));

        assertEquals(attrNames, rows.get(0));

        rows = parseSystemViewCommandOutput(
            executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, toSqlName(sysViewName).toLowerCase(), NODE_ID.argName(), nodeId));

        assertEquals(attrNames, rows.get(0));

        rows = parseSystemViewCommandOutput(
            executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, sysViewName, NODE_ID.argName(), nodeId));

        assertEquals(attrNames, rows.remove(0));

        int attrsCnt = sysView.walker().count();

        rows.forEach(row -> assertEquals(attrsCnt, row.size()));

        return rows;
    }

    /**
     * Obtains system view values for each row from command output.
     *
     * @param out Command output to parse.
     * @return System view values.
     */
    private List<List<String>> parseSystemViewCommandOutput(String out) {
        String outStart = "--------------------------------------------------------------------------------";

        String outEnd = "Command [" + SYSTEM_VIEW.toCommandName() + "] finished with code: " + EXIT_CODE_OK;

        List<String> rows = Arrays.asList(out.substring(
            out.indexOf(outStart) + outStart.length() + 1,
            out.indexOf(outEnd) - 1
        ).split(U.nl()));

        return rows.stream().map(row ->
            Arrays.stream(row.split(quote(COLUMN_SEPARATOR)))
                .map(String::trim)
                .filter(str -> !str.isEmpty())
                .collect(Collectors.toList()))
            .collect(Collectors.toList());
    }

    /**
     * Executes command and checks its exit code.
     *
     * @param expExitCode Expected exit code.
     * @param args Command lines arguments.
     * @return Result of command execution.
     */
    private String executeCommand(int expExitCode, String... args) {
        int res = execute(args);

        assertEquals(expExitCode, res);

        return testOut.toString();
    }
}
