@SuppressWarnings("JdkObsolete")
    void runNonGui(String testFile, String logFile, boolean remoteStart, String remoteHostsString, boolean generateReportDashboard)
            throws ConfigurationException {
        try {
            File f = new File(testFile);
            if (!f.exists() || !f.isFile()) {
                throw new ConfigurationException("The file " + f.getAbsolutePath() + " doesn't exist or can't be opened");
            }
            FileServer.getFileServer().setBaseForScript(f);

            HashTree tree = SaveService.loadTree(f);

            @SuppressWarnings("deprecation") // Deliberate use of deprecated ctor
            JMeterTreeModel treeModel = new JMeterTreeModel(new Object());// NOSONAR Create non-GUI version to avoid headless problems
            JMeterTreeNode root = (JMeterTreeNode) treeModel.getRoot();
            treeModel.addSubTree(tree, root);

            // Hack to resolve ModuleControllers in non GUI mode
            SearchByClass<ReplaceableController> replaceableControllers =
                    new SearchByClass<>(ReplaceableController.class);
            tree.traverse(replaceableControllers);
            Collection<ReplaceableController> replaceableControllersRes = replaceableControllers.getSearchResults();
            for (ReplaceableController replaceableController : replaceableControllersRes) {
                replaceableController.resolveReplacementSubTree(root);
            }

            // Ensure tree is interpreted (ReplaceableControllers are replaced)
            // For GUI runs this is done in Start.java
            HashTree clonedTree = convertSubTree(tree, true);

            Summariser summariser = null;
            String summariserName = JMeterUtils.getPropDefault("summariser.name", "");//$NON-NLS-1$
            if (summariserName.length() > 0) {
                log.info("Creating summariser <{}>", summariserName);
                println("Creating summariser <" + summariserName + ">");
                summariser = new Summariser(summariserName);
            }
            ResultCollector resultCollector = null;
            if (logFile != null) {
                resultCollector = new ResultCollector(summariser);
                resultCollector.setFilename(logFile);
                clonedTree.add(clonedTree.getArray()[0], resultCollector);
            }
            else {
                // only add Summariser if it can not be shared with the ResultCollector
                if (summariser != null) {
                    clonedTree.add(clonedTree.getArray()[0], summariser);
                }
            }

            if (deleteResultFile) {
                SearchByClass<ResultCollector> resultListeners = new SearchByClass<>(ResultCollector.class);
                clonedTree.traverse(resultListeners);
                for (ResultCollector rc : resultListeners.getSearchResults()) {
                    File resultFile = new File(rc.getFilename());
                    if (resultFile.exists() && !resultFile.delete()) {
                        throw new IllegalStateException("Could not delete results file " + resultFile.getAbsolutePath()
                                + "(canRead:" + resultFile.canRead() + ", canWrite:" + resultFile.canWrite() + ")");
                    }
                }
            }
            ReportGenerator reportGenerator = null;
            if (logFile != null && generateReportDashboard) {
                reportGenerator = new ReportGenerator(logFile, resultCollector);
            }

            // Used for remote notification of threads start/stop,see BUG 54152
            // Summariser uses this feature to compute correctly number of threads
            // when NON GUI mode is used
            clonedTree.add(clonedTree.getArray()[0], new RemoteThreadsListenerTestElement());

            List<JMeterEngine> engines = new ArrayList<>();
            println("Created the tree successfully using "+testFile);
            if (!remoteStart) {
                JMeterEngine engine = new StandardJMeterEngine();
                clonedTree.add(clonedTree.getArray()[0], new ListenToTest(
                        org.apache.jmeter.JMeter.ListenToTest.RunMode.LOCAL, false, reportGenerator));
                engine.configure(clonedTree);
                Instant now = Instant.now();
                println("Starting standalone test @ "+ formatLikeDate(now) + " (" + now.toEpochMilli() + ')');
                engines.add(engine);
                engine.runTest();
            } else {
                java.util.StringTokenizer st = new java.util.StringTokenizer(remoteHostsString.trim(), ",");//$NON-NLS-1$
                List<String> hosts = new ArrayList<>();
                while (st.hasMoreElements()) {
                    hosts.add(((String) st.nextElement()).trim());
                }
                ListenToTest testListener = new ListenToTest(
                        org.apache.jmeter.JMeter.ListenToTest.RunMode.REMOTE, remoteStop, reportGenerator);
                clonedTree.add(clonedTree.getArray()[0], testListener);
                DistributedRunner distributedRunner=new DistributedRunner(this.remoteProps);
                distributedRunner.setStdout(System.out); // NOSONAR
                distributedRunner.setStdErr(System.err); // NOSONAR
                distributedRunner.init(hosts, clonedTree);
                engines.addAll(distributedRunner.getEngines());
                testListener.setStartedRemoteEngines(engines);
                distributedRunner.start();
            }
            startUdpDdaemon(engines);
        } catch (ConfigurationException e) {
            throw e;
        } catch (Exception e) {
            System.out.println("Error in NonGUIDriver " + e.toString());//NOSONAR
            log.error("Error in NonGUIDriver", e);
            throw new ConfigurationException("Error in NonGUIDriver " + e.getMessage(), e);
        }
    }
@Test
    void testSuccessWhenJmxExists() throws IOException, ConfigurationException {
        File temp = File.createTempFile("testPlan", ".jmx");
        String testPlan = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                + "<jmeterTestPlan version=\"1.2\" properties=\"5.0\" jmeter=\"5.2-SNAPSHOT\">\n" + "  <hashTree>\n"
                + "    <TestPlan guiclass=\"TestPlanGui\" testclass=\"TestPlan\" testname=\"Test Plan\" enabled=\"true\">\n"
                + "      <stringProp name=\"TestPlan.comments\"></stringProp>\n"
                + "      <boolProp name=\"TestPlan.functional_mode\">false</boolProp>\n"
                + "      <boolProp name=\"TestPlan.tearDown_on_shutdown\">true</boolProp>\n"
                + "      <boolProp name=\"TestPlan.serialize_threadgroups\">false</boolProp>\n"
                + "      <elementProp name=\"TestPlan.user_defined_variables\" elementType=\"Arguments\" guiclass=\"ArgumentsPanel\" "
                + "testclass=\"Arguments\" testname=\"User Defined Variables\" enabled=\"true\">\n"
                + "        <collectionProp name=\"Arguments.arguments\"/>\n" + "      </elementProp>\n"
                + "      <stringProp name=\"TestPlan.user_define_classpath\"></stringProp></TestPlan>"
                + "    <hashTree/></hashTree></jmeterTestPlan>";
        try (FileOutputStream os = new FileOutputStream(temp);
                Writer fw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
                BufferedWriter out = new BufferedWriter(fw)) {
            out.write(testPlan);
        }

        try {
            JMeter jmeter = new JMeter();
            jmeter.runNonGui(temp.getAbsolutePath(), null, false, null, false);
        } finally {
            Assertions.assertTrue(temp.delete(), () ->"File " + temp.getAbsolutePath() + " should have been deleted");
        }
    }