public PartialResultQueryTaskTracker(
            PartialResultQueryManager partialResultQueryManager,
            double minCompletionRatioThreshold,
            double timeMultiplier,
            WarningCollector warningCollector)
    {
        this.partialResultQueryManager = requireNonNull(partialResultQueryManager, "partialResultQueryManager is null");
        this.minCompletionRatioThreshold = minCompletionRatioThreshold;
        this.timeMultiplier = timeMultiplier;
        this.warningCollector = requireNonNull(warningCollector, "warningCollector is null");
        this.startTime = System.nanoTime();
    }
@Test
    public void testPartialResultQueryTaskTracker()
            throws Exception
    {
        PartialResultQueryTaskTracker tracker = new PartialResultQueryTaskTracker(partialResultQueryManager, 0.50, 2.0, warningCollector);
        InternalNode node1 = new InternalNode(
                UUID.randomUUID().toString(),
                URI.create("https://192.0.2.8"),
                new NodeVersion("1"),
                false,
                false,
                false,
                false);
        InternalNode node2 = new InternalNode(
                UUID.randomUUID().toString(),
                URI.create("https://192.0.2.9"),
                new NodeVersion("1"),
                false,
                false,
                false,
                false);
        TaskId taskId1 = new TaskId("test1", 1, 0, 1, 0);
        TaskId taskId2 = new TaskId("test2", 2, 0, 1, 0);
        RemoteTask task1 = taskFactory.createTableScanTask(taskId1, node1, ImmutableList.of(), new NodeTaskMap.NodeStatsTracker(delta -> {}, delta -> {}, (age, delta) -> {}));
        RemoteTask task2 = taskFactory.createTableScanTask(taskId2, node2, ImmutableList.of(), new NodeTaskMap.NodeStatsTracker(delta -> {}, delta -> {}, (age, delta) -> {}));

        tracker.trackTask(task1);
        tracker.trackTask(task2);

        // Assert that completion ratio is 0.0 since the tasks did not complete yet
        assertEquals(0.0, tracker.getTaskCompletionRatio());

        tracker.completeTaskScheduling();

        tracker.recordTaskFinish(task1.getTaskInfo());
        // Assert that completion ratio is 0.5 since we have set that task1 finished in above line
        assertEquals(0.5, tracker.getTaskCompletionRatio());

        // Assert that the query is added to query manager, queue size = 1 since the query reached minCompletion ratio of 0.5 and is eligible for partial results
        assertEquals(1, partialResultQueryManager.getQueueSize());

        // Sleep for 6 seconds so that we give enough time for query manager to cancel tasks and complete the query with partial results
        Thread.sleep(6000);
        assertEquals(0, partialResultQueryManager.getQueueSize());

        // Assert that partial result warning is set correctly
        assertEquals(1, warningCollector.getWarnings().size());
        PrestoWarning prestoWarning = warningCollector.getWarnings().get(0);

        // Assert that warning code is set to PARTIAL_RESULT_WARNING
        assertEquals(PARTIAL_RESULT_WARNING.toWarningCode(), prestoWarning.getWarningCode());

        // Assert that completion percent of 50.00 is specified correctly in the warning message
        assertEquals("Partial results are returned. Only 50.00 percent of the data is read.", prestoWarning.getMessage());
    }