File indexing completed on 2024-04-14 14:12:09
0001 /* KStars UI tests 0002 SPDX-FileCopyrightText: 2020 Eric Dejouhanet <eric.dejouhanet@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 0008 #include "test_ekos_scheduler.h" 0009 0010 #if defined(HAVE_INDI) 0011 0012 #include "kstars_ui_tests.h" 0013 #include "test_ekos.h" 0014 #include "test_ekos_simulator.h" 0015 #include "ekos/scheduler/scheduler.h" 0016 0017 TestEkosScheduler::TestEkosScheduler(QObject *parent) : QObject(parent) 0018 { 0019 } 0020 0021 void TestEkosScheduler::init() 0022 { 0023 } 0024 0025 void TestEkosScheduler::cleanup() 0026 { 0027 } 0028 0029 void TestEkosScheduler::initTestCase() 0030 { 0031 KVERIFY_EKOS_IS_HIDDEN(); 0032 KTRY_OPEN_EKOS(); 0033 KVERIFY_EKOS_IS_OPENED(); 0034 KTRY_EKOS_START_SIMULATORS(); 0035 0036 // HACK: Reset clock to initial conditions 0037 KHACK_RESET_EKOS_TIME(); 0038 } 0039 0040 void TestEkosScheduler::cleanupTestCase() 0041 { 0042 KTRY_EKOS_STOP_SIMULATORS(); 0043 KTRY_CLOSE_EKOS(); 0044 KVERIFY_EKOS_IS_HIDDEN(); 0045 } 0046 0047 void TestEkosScheduler::testScheduleManipulation_data() 0048 { 0049 #if 0 0050 #if QT_VERSION < 0x050900 0051 QSKIP("Skipping fixture-based test on old QT version."); 0052 #else 0053 QTest::addColumn<QString>("NAME"); 0054 QTest::addColumn<QString>("RA"); 0055 QTest::addColumn<QString>("DEC"); 0056 0057 // Altitude computation taken from SchedulerJob::findAltitude 0058 GeoLocation * const geo = KStarsData::Instance()->geo(); 0059 KStarsDateTime const now(KStarsData::Instance()->lt()); 0060 KSNumbers const numbers(now.djd()); 0061 CachingDms const LST = geo->GSTtoLST(geo->LTtoUT(now).gst()); 0062 0063 std::list<char const *> Objects = { "Polaris", "Mizar", "M 51", "M 13", "M 47", "Vega", "NGC 2238", "M 81" }; 0064 size_t count = 0; 0065 0066 foreach (char const *name, Objects) 0067 { 0068 SkyObject const * const so = KStars::Instance()->data()->objectNamed(name); 0069 if (so != nullptr) 0070 { 0071 SkyObject o(*so); 0072 o.updateCoordsNow(&numbers); 0073 o.EquatorialToHorizontal(&LST, geo->lat()); 0074 if (10.0 < o.alt().Degrees()) 0075 { 0076 QTest::addRow("%s", name) 0077 << name 0078 << o.ra().toHMSString() 0079 << o.dec().toDMSString(); 0080 count++; 0081 } 0082 else QWARN(QString("Fixture '%1' altitude is '%2' degrees, discarding.").arg(name).arg( 0083 so->alt().Degrees()).toStdString().c_str()); 0084 } 0085 } 0086 0087 if (!count) 0088 QSKIP("No usable fixture objects, bypassing test."); 0089 #endif 0090 #endif 0091 } 0092 0093 void TestEkosScheduler::testScheduleManipulation() 0094 { 0095 Ekos::Manager * const ekos = Ekos::Manager::Instance(); 0096 0097 // Wait for Scheduler to come up, switch to Scheduler tab 0098 QTRY_VERIFY_WITH_TIMEOUT(ekos->schedulerModule() != nullptr, 5000); 0099 KTRY_EKOS_GADGET(QTabWidget, toolsWidget); 0100 toolsWidget->setCurrentWidget(ekos->schedulerModule()); 0101 QTRY_COMPARE_WITH_TIMEOUT(toolsWidget->currentWidget(), ekos->schedulerModule(), 1000); 0102 0103 KTRY_SCHEDULER_GADGET(QLineEdit, nameEdit); 0104 KTRY_SCHEDULER_GADGET(dmsBox, raBox); 0105 KTRY_SCHEDULER_GADGET(dmsBox, decBox); 0106 KTRY_SCHEDULER_GADGET(QLineEdit, sequenceEdit); 0107 KTRY_SCHEDULER_GADGET(QPushButton, addToQueueB); 0108 KTRY_SCHEDULER_GADGET(QPushButton, removeFromQueueB); 0109 0110 // Computation taken from SchedulerJob::findAltitude 0111 GeoLocation * const geo = KStarsData::Instance()->geo(); 0112 KStarsDateTime const now(KStarsData::Instance()->lt()); 0113 KSNumbers const numbers(now.djd()); 0114 CachingDms const LST = geo->GSTtoLST(geo->LTtoUT(now).gst()); 0115 0116 raBox->setText("1h 2' 3\""); 0117 decBox->setText("1° 2' 3\""); 0118 sequenceEdit->setText(QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg( 0119 QDir::separator())); // %20 to retain the next '1' 0120 0121 QEXPECT_FAIL("", "The sequence file editbox cannot be edited directly, and changing its text does not allow to add a job", 0122 Continue); 0123 QTRY_VERIFY_WITH_TIMEOUT(addToQueueB->isEnabled(), 200); 0124 0125 const int count = 20; 0126 QStringList seqs; 0127 seqs << QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg( 0128 QDir::separator()); // %20 to retain the next '1' 0129 seqs << QString("%1%201x1s_RGBLumRGB.esq").arg(QDir::current().currentPath()).arg( 0130 QDir::separator()); // %20 to retain the next '1' 0131 0132 KTRY_SCHEDULER_GADGET(QTableWidget, queueTable); 0133 0134 // Add objects to the schedule 0135 for (int i = 0; i < count; i++) 0136 { 0137 QCOMPARE(queueTable->rowCount(), i); 0138 0139 nameEdit->setText(QString("Object-%1").arg(i)); 0140 0141 SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); 0142 raBox->setText(o.ra().toHMSString()); 0143 QVERIFY(abs(raBox->createDms().Hours() - o.ra().Hours()) <= 15.0 / 3600.0); 0144 decBox->setText(o.dec().toDMSString()); 0145 QVERIFY(abs(decBox->createDms().Degrees() - o.dec().Degrees()) <= 1.0 / 3600.0); 0146 sequenceEdit->setText(seqs[i % seqs.count()]); 0147 0148 Ekos::Manager::Instance()->schedulerModule()->addObject(&o); 0149 Ekos::Manager::Instance()->schedulerModule()->setSequence(sequenceEdit->text()); 0150 nameEdit->setText(QString("Object-%1").arg(i)); 0151 0152 // Add object -- note adding can be quite slow 0153 KTRY_SCHEDULER_CLICK(addToQueueB); 0154 QTRY_COMPARE_WITH_TIMEOUT(queueTable->rowCount(), i + 1, 5000); 0155 } 0156 0157 // Verify each row 0158 for (int i = 0; i < count; i++) 0159 { 0160 queueTable->selectRow(i % queueTable->rowCount()); 0161 QCOMPARE(qPrintable(nameEdit->text()), qPrintable(QString("Object-%1").arg(i))); 0162 QCOMPARE(qPrintable(sequenceEdit->text()), qPrintable(seqs[i % seqs.count()])); 0163 SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); 0164 QCOMPARE(qPrintable(dms::fromString(raBox->text(), false).toHMSString()), qPrintable(o.ra().toHMSString())); 0165 QCOMPARE(qPrintable(dms::fromString(decBox->text(), true).toDMSString()), qPrintable(o.dec().toDMSString())); 0166 } 0167 0168 // Select a job, remove it and press the add button. the old one should be added below 0169 // This verifies the fix to the issue causing sequence files to be messed up when pasting jobs 0170 for (int i = count - 2; i > 0; i--) 0171 { 0172 queueTable->selectRow(std::min(i, queueTable->rowCount() - 1)); 0173 0174 KTRY_SCHEDULER_CLICK(removeFromQueueB); 0175 KTRY_SCHEDULER_CLICK(addToQueueB); 0176 queueTable->selectRow(std::min(i + 1, queueTable->rowCount() - 1)); 0177 0178 QCOMPARE(qPrintable(nameEdit->text()), qPrintable(QString("Object-%1").arg(i))); 0179 QCOMPARE(qPrintable(sequenceEdit->text()), qPrintable(seqs[i % seqs.count()])); 0180 SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); 0181 QCOMPARE(qPrintable(dms::fromString(raBox->text(), false).toHMSString()), qPrintable(o.ra().toHMSString())); 0182 QCOMPARE(qPrintable(dms::fromString(decBox->text(), true).toDMSString()), qPrintable(o.dec().toDMSString())); 0183 } 0184 0185 // Remove objects from the schedule 0186 for (int i = 0; i < count; i++) 0187 { 0188 QCOMPARE(queueTable->rowCount(), count - i); 0189 0190 //QEXPECT_FAIL("", "Removal button is ineffective when there is no line selection.", Continue); 0191 //QTRY_COMPARE_WITH_TIMEOUT(queueTable->rowCount(), count - i, 5000); 0192 0193 // Select a line, remove job - note removal can be quite slow 0194 const int pos = i % queueTable->rowCount(); 0195 queueTable->selectRow(pos); 0196 //queueTable->selectionModel()->select(queueTable->model()->index(i % queueTable->model()->rowCount(), 0), QItemSelectionModel::SelectCurrent); 0197 KTRY_SCHEDULER_CLICK(removeFromQueueB); 0198 QTRY_COMPARE_WITH_TIMEOUT(queueTable->rowCount(), count - i - 1, 5000); 0199 0200 // After a removal, no row is selected, no further removal possible 0201 QVERIFY(!removeFromQueueB->isEnabled()); 0202 } 0203 0204 QCOMPARE(queueTable->rowCount(), 0); 0205 } 0206 0207 QTEST_KSTARS_MAIN(TestEkosScheduler) 0208 0209 #endif // HAVE_INDI