1 /*
2 SPDX-FileCopyrightText: 2021 Kwon-Young Choi <kwon-young.choi@hotmail.fr>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 /* Project Includes */
8 #include "test_placeholderpath.h"
9 #include "ekos/capture/sequencejob.h"
10 #include "ekos/scheduler/schedulerjob.h"
11 #include "ekos/capture/placeholderpath.h"
12
13 #include <QFile>
14 #include <QRegularExpression>
15 #include <QRegularExpressionMatch>
16
TestPlaceholderPath()17 TestPlaceholderPath::TestPlaceholderPath() : QObject()
18 {
19 }
20
~TestPlaceholderPath()21 TestPlaceholderPath::~TestPlaceholderPath()
22 {
23 }
24
25 // helper functions
parseCSV(const QString filename,const QList<const char * > columns)26 void parseCSV(const QString filename, const QList<const char*> columns)
27 {
28 QFile testDataFile(filename);
29
30 if (!testDataFile.open(QIODevice::ReadOnly))
31 {
32 qDebug() << testDataFile.errorString();
33 QFAIL("error");
34 }
35
36 // checking csv header
37 int columnCpt = 0;
38 QByteArray line = testDataFile.readLine().replace("\n", "");
39
40 for (auto el : line.split(','))
41 {
42 if (columns.size() <= columnCpt)
43 QFAIL("too many csv columns");
44 else if (el != columns[columnCpt])
45 {
46 QFAIL(QString("csv columns incorrect %1 %2").arg(el, columns[columnCpt]).toStdString().c_str());
47 }
48 columnCpt++;
49 }
50
51 if (columns.size() != columnCpt)
52 QFAIL("not enough csv columns");
53
54 int cpt = 0;
55
56 while (!testDataFile.atEnd())
57 {
58 QByteArray line = testDataFile.readLine().replace("\n", "");
59 QTestData &row = QTest::addRow("%d", cpt);
60 for (auto el : line.split(','))
61 {
62 row << QString::fromStdString(el.toStdString());
63 }
64 cpt++;
65 }
66 }
67
buildXML(QString Exposure,QString Filter,QString Type,QString Prefix,QString RawPrefix,QString FilterEnabled,QString ExpEnabled,QString TimeStampEnabled,QString FITSDirectory)68 XMLEle* buildXML(
69 QString Exposure,
70 QString Filter,
71 QString Type,
72 QString Prefix,
73 QString RawPrefix,
74 QString FilterEnabled,
75 QString ExpEnabled,
76 QString TimeStampEnabled,
77 QString FITSDirectory
78 )
79 {
80 XMLEle *root = NULL;
81 XMLEle *ep, *subEP;
82 root = addXMLEle(root, "root");
83
84 if (!Exposure.isEmpty())
85 {
86 ep = addXMLEle(root, "Exposure");
87 editXMLEle(ep, Exposure.toStdString().c_str());
88 }
89
90 if (!Filter.isEmpty())
91 {
92 ep = addXMLEle(root, "Filter");
93 editXMLEle(ep, Filter.toStdString().c_str());
94 }
95
96 if (!Type.isEmpty())
97 {
98 ep = addXMLEle(root, "Type");
99 editXMLEle(ep, Type.toStdString().c_str());
100 }
101
102 if (!Prefix.isEmpty())
103 {
104 ep = addXMLEle(root, "Prefix");
105 if (!RawPrefix.isEmpty())
106 {
107 subEP = addXMLEle(ep, "RawPrefix");
108 editXMLEle(subEP, RawPrefix.toStdString().c_str());
109 }
110 if (!FilterEnabled.isEmpty())
111 {
112 subEP = addXMLEle(ep, "FilterEnabled");
113 editXMLEle(subEP, FilterEnabled.toStdString().c_str());
114 }
115 if (!ExpEnabled.isEmpty())
116 {
117 subEP = addXMLEle(ep, "ExpEnabled");
118 editXMLEle(subEP, ExpEnabled.toStdString().c_str());
119 }
120 if (!TimeStampEnabled.isEmpty())
121 {
122 subEP = addXMLEle(ep, "TimeStampEnabled");
123 editXMLEle(subEP, TimeStampEnabled.toStdString().c_str());
124 }
125 }
126
127 if (!FITSDirectory.isEmpty())
128 {
129 ep = addXMLEle(root, "FITSDirectory");
130 editXMLEle(ep, FITSDirectory.toStdString().c_str());
131 }
132
133 //prXMLEle(stdout, root, 0);
134
135 return root;
136 }
137
testSchedulerProcessJobInfo_data()138 void TestPlaceholderPath::testSchedulerProcessJobInfo_data()
139 {
140 #if QT_VERSION < 0x050900
141 QSKIP("Skipping fixture-based test on old QT version.");
142 #else
143 const QList<const char*> columns =
144 {
145 "Exposure",
146 "Filter",
147 "Type",
148 "Prefix",
149 "RawPrefix",
150 "FilterEnabled",
151 "ExpEnabled",
152 "FITSDirectory",
153 "targetName",
154 "signature",
155 };
156 for (const auto &column : columns)
157 {
158 QTest::addColumn<QString>(column);
159 }
160 parseCSV(":/testSchedulerProcessJobInfo_data.csv", columns);
161
162 #endif
163 }
164
testSchedulerProcessJobInfo()165 void TestPlaceholderPath::testSchedulerProcessJobInfo()
166 {
167 #if QT_VERSION < 0x050900
168 QSKIP("Skipping fixture-based test on old QT version.");
169 #else
170 QFETCH(QString, Exposure);
171 QFETCH(QString, Filter);
172 QFETCH(QString, Type);
173 QFETCH(QString, Prefix);
174 QFETCH(QString, RawPrefix);
175 QFETCH(QString, FilterEnabled);
176 QFETCH(QString, ExpEnabled);
177 QFETCH(QString, FITSDirectory);
178 /*
179 * replace \s / ( ) : * ~ " characters by _
180 * Remove any two or more __ by _
181 * Remove any _ at the end
182 */
183 QFETCH(QString, targetName);
184 QFETCH(QString, signature);
185
186 XMLEle *root = buildXML(
187 Exposure,
188 Filter,
189 Type,
190 Prefix,
191 RawPrefix,
192 FilterEnabled,
193 ExpEnabled,
194 "",
195 FITSDirectory);
196
197 Ekos::SequenceJob job(root);
198 QCOMPARE(job.getFilterName(), Filter);
199 auto placeholderPath = Ekos::PlaceholderPath();
200 placeholderPath.processJobInfo(&job, targetName);
201
202 QCOMPARE(job.getSignature(), signature);
203
204 delXMLEle(root);
205 #endif
206 }
207
testCaptureAddJob_data()208 void TestPlaceholderPath::testCaptureAddJob_data()
209 {
210 #if QT_VERSION < 0x050900
211 QSKIP("Skipping fixture-based test on old QT version.");
212 #else
213 const QList<const char*> columns =
214 {
215 "Exposure",
216 "Filter",
217 "Type",
218 "Prefix",
219 "RawPrefix",
220 "FilterEnabled",
221 "ExpEnabled",
222 "FITSDirectory",
223 "targetName",
224 "signature",
225 };
226 for (const auto &column : columns)
227 {
228 QTest::addColumn<QString>(column);
229 }
230 parseCSV(":/testSchedulerProcessJobInfo_data.csv", columns);
231 #endif
232 }
233
testCaptureAddJob()234 void TestPlaceholderPath::testCaptureAddJob()
235 {
236 #if QT_VERSION < 0x050900
237 QSKIP("Skipping fixture-based test on old QT version.");
238 #else
239 QFETCH(QString, Exposure);
240 QFETCH(QString, Filter);
241 QFETCH(QString, Type);
242 QFETCH(QString, Prefix);
243 QFETCH(QString, RawPrefix);
244 QFETCH(QString, FilterEnabled);
245 QFETCH(QString, ExpEnabled);
246 QFETCH(QString, FITSDirectory);
247 /*
248 * replace \s / ( ) : * ~ " characters by _
249 * Remove any two or more __ by _
250 * Remove any _ at the end
251 */
252 QFETCH(QString, targetName);
253 QFETCH(QString, signature);
254
255 XMLEle *root = buildXML(
256 Exposure,
257 Filter,
258 Type,
259 Prefix,
260 RawPrefix,
261 FilterEnabled,
262 ExpEnabled,
263 "",
264 FITSDirectory);
265
266 // for addJob, targetName should already be sanitized
267 // taken from scheduler.cpp:2491-2495
268 targetName = targetName.replace( QRegularExpression("\\s|/|\\(|\\)|:|\\*|~|\"" ), "_" )
269 // Remove any two or more __
270 .replace( QRegularExpression("_{2,}"), "_")
271 // Remove any _ at the end
272 .replace( QRegularExpression("_$"), "");
273 Ekos::SequenceJob job(root);
274 QCOMPARE(job.getFilterName(), Filter);
275 auto placeholderPath = Ekos::PlaceholderPath();
276 placeholderPath.addJob(&job, targetName);
277
278 QCOMPARE(job.getSignature(), signature);
279
280 delXMLEle(root);
281 #endif
282 }
283
testCCDGenerateFilename_data()284 void TestPlaceholderPath::testCCDGenerateFilename_data()
285 {
286 #if QT_VERSION < 0x050900
287 QSKIP("Skipping fixture-based test on old QT version.");
288 #else
289 QTest::addColumn<QString>("format");
290 QTest::addColumn<bool>("batch_mode");
291 QTest::addColumn<QString>("fitsDir");
292 QTest::addColumn<QString>("seqPrefix");
293 QTest::addColumn<int>("nextSequenceID");
294 QTest::addColumn<QString>("desiredFilename");
295
296 // format
297 QTest::addRow("0") << "" << false << "" << "" << 0 << "/.+/kstars/000";
298 QTest::addRow("1") << "" << false << "" << "" << 1 << "/.+/kstars/001";
299 QTest::addRow("2") << "" << false << "" << "_ISO8601" << 0 <<
300 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
301 QTest::addRow("3") << "" << false << "" << "_ISO8601" << 1 <<
302 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
303 QTest::addRow("4") << "" << false << "" << "_ISO8601bar" << 0 <<
304 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
305 QTest::addRow("5") << "" << false << "" << "_ISO8601bar" << 1 <<
306 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
307 QTest::addRow("6") << "" << false << "" << "bar" << 0 << "/.+/kstars/bar_000";
308 QTest::addRow("7") << "" << false << "" << "bar" << 1 << "/.+/kstars/bar_001";
309 QTest::addRow("8") << "" << false << "foo" << "" << 0 << "/.+/kstars/000";
310 QTest::addRow("9") << "" << false << "foo" << "" << 1 << "/.+/kstars/001";
311 QTest::addRow("10") << "" << false << "foo" << "_ISO8601" << 0 <<
312 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
313 QTest::addRow("11") << "" << false << "foo" << "_ISO8601" << 1 <<
314 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
315 QTest::addRow("12") << "" << false << "foo" << "_ISO8601bar" << 0 <<
316 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
317 QTest::addRow("13") << "" << false << "foo" << "_ISO8601bar" << 1 <<
318 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
319 QTest::addRow("14") << "" << false << "foo" << "bar" << 0 << "/.+/kstars/bar_000";
320 QTest::addRow("15") << "" << false << "foo" << "bar" << 1 << "/.+/kstars/bar_001";
321 QTest::addRow("16") << "" << true << "" << "" << 0 << "/.+/000";
322 QTest::addRow("17") << "" << true << "" << "" << 1 << "/.+/001";
323 QTest::addRow("18") << "" << true << "" << "_ISO8601" << 0 <<
324 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
325 QTest::addRow("19") << "" << true << "" << "_ISO8601" << 1 <<
326 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
327 QTest::addRow("20") << "" << true << "" << "_ISO8601bar" << 0 <<
328 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
329 QTest::addRow("21") << "" << true << "" << "_ISO8601bar" << 1 <<
330 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
331 QTest::addRow("22") << "" << true << "" << "bar" << 0 << "/.+/bar_000";
332 QTest::addRow("23") << "" << true << "" << "bar" << 1 << "/.+/bar_001";
333 QTest::addRow("24") << "" << true << "foo" << "" << 0 << "foo/000";
334 QTest::addRow("25") << "" << true << "foo" << "" << 1 << "foo/001";
335 QTest::addRow("26") << "" << true << "foo" << "_ISO8601" << 0 <<
336 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
337 QTest::addRow("27") << "" << true << "foo" << "_ISO8601" << 1 <<
338 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
339 QTest::addRow("28") << "" << true << "foo" << "_ISO8601bar" << 0 <<
340 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
341 QTest::addRow("29") << "" << true << "foo" << "_ISO8601bar" << 1 <<
342 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
343 QTest::addRow("30") << "" << true << "foo" << "bar" << 0 << "foo/bar_000";
344 QTest::addRow("31") << "" << true << "foo" << "bar" << 1 << "foo/bar_001";
345 QTest::addRow("32") << ".fits" << false << "" << "" << 0 << "/.+/kstars/000.fits";
346 QTest::addRow("33") << ".fits" << false << "" << "" << 1 << "/.+/kstars/001.fits";
347 QTest::addRow("34") << ".fits" << false << "" << "_ISO8601" << 0 <<
348 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
349 QTest::addRow("35") << ".fits" << false << "" << "_ISO8601" << 1 <<
350 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
351 QTest::addRow("36") << ".fits" << false << "" << "_ISO8601bar" << 0 <<
352 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
353 QTest::addRow("37") << ".fits" << false << "" << "_ISO8601bar" << 1 <<
354 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
355 QTest::addRow("38") << ".fits" << false << "" << "bar" << 0 << "/.+/kstars/bar_000.fits";
356 QTest::addRow("39") << ".fits" << false << "" << "bar" << 1 << "/.+/kstars/bar_001.fits";
357 QTest::addRow("40") << ".fits" << false << "foo" << "" << 0 << "/.+/kstars/000.fits";
358 QTest::addRow("41") << ".fits" << false << "foo" << "" << 1 << "/.+/kstars/001.fits";
359 QTest::addRow("42") << ".fits" << false << "foo" << "_ISO8601" << 0 <<
360 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
361 QTest::addRow("43") << ".fits" << false << "foo" << "_ISO8601" << 1 <<
362 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
363 QTest::addRow("44") << ".fits" << false << "foo" << "_ISO8601bar" << 0 <<
364 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
365 QTest::addRow("45") << ".fits" << false << "foo" << "_ISO8601bar" << 1 <<
366 "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
367 QTest::addRow("46") << ".fits" << false << "foo" << "bar" << 0 << "/.+/kstars/bar_000.fits";
368 QTest::addRow("47") << ".fits" << false << "foo" << "bar" << 1 << "/.+/kstars/bar_001.fits";
369 QTest::addRow("48") << ".fits" << true << "" << "" << 0 << "/.+/000.fits";
370 QTest::addRow("49") << ".fits" << true << "" << "" << 1 << "/.+/001.fits";
371 QTest::addRow("50") << ".fits" << true << "" << "_ISO8601" << 0 <<
372 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
373 QTest::addRow("51") << ".fits" << true << "" << "_ISO8601" << 1 <<
374 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
375 QTest::addRow("52") << ".fits" << true << "" << "_ISO8601bar" << 0 <<
376 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
377 QTest::addRow("53") << ".fits" << true << "" << "_ISO8601bar" << 1 <<
378 "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
379 QTest::addRow("54") << ".fits" << true << "" << "bar" << 0 << "/.+/bar_000.fits";
380 QTest::addRow("55") << ".fits" << true << "" << "bar" << 1 << "/.+/bar_001.fits";
381 QTest::addRow("56") << ".fits" << true << "foo" << "" << 0 << "foo/000.fits";
382 QTest::addRow("57") << ".fits" << true << "foo" << "" << 1 << "foo/001.fits";
383 QTest::addRow("58") << ".fits" << true << "foo" << "_ISO8601" << 0 <<
384 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
385 QTest::addRow("59") << ".fits" << true << "foo" << "_ISO8601" << 1 <<
386 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
387 QTest::addRow("60") << ".fits" << true << "foo" << "_ISO8601bar" << 0 <<
388 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
389 QTest::addRow("61") << ".fits" << true << "foo" << "_ISO8601bar" << 1 <<
390 "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
391 QTest::addRow("62") << ".fits" << true << "foo" << "bar" << 0 << "foo/bar_000.fits";
392 QTest::addRow("63") << ".fits" << true << "foo" << "bar" << 1 << "foo/bar_001.fits";
393 #endif
394 }
395
testCCDGenerateFilename()396 void TestPlaceholderPath::testCCDGenerateFilename()
397 {
398 #if QT_VERSION < 0x050900
399 QSKIP("Skipping fixture-based test on old QT version.");
400 #else
401 QFETCH(QString, format);
402 QFETCH(bool, batch_mode);
403 QFETCH(QString, fitsDir);
404 QFETCH(QString, seqPrefix);
405 QFETCH(int, nextSequenceID);
406 QFETCH(QString, desiredFilename);
407
408 QString filename;
409 auto placeholderPath = Ekos::PlaceholderPath();
410 placeholderPath.generateFilenameOld(format, batch_mode, &filename, fitsDir, seqPrefix, nextSequenceID);
411
412 QVERIFY(QRegularExpression(desiredFilename).match(filename).hasMatch());
413 #endif
414 }
415
testSequenceJobSignature_data()416 void TestPlaceholderPath::testSequenceJobSignature_data()
417 {
418 #if QT_VERSION < 0x050900
419 QSKIP("Skipping fixture-based test on old QT version.");
420 #else
421 QTest::addColumn<QString>("localDir");
422 QTest::addColumn<QString>("directoryPostfix");
423 QTest::addColumn<QString>("fullPrefix");
424 QTest::addColumn<QString>("signature");
425
426 QTest::addRow("empty") << "" << "" << "" << "/";
427 QTest::addRow("localDir") << "/foo" << "" << "" << "/foo/";
428 QTest::addRow("directoryPostfix") << "" << "bar" << "" << "bar/";
429 QTest::addRow("fullPrefix") << "" << "" << "toto" << "/toto";
430 QTest::addRow("localDir+directoryPostfix") << "/foo" << "bar" << "" << "/foobar/";
431 QTest::addRow("directoryPostfix+fullPrefix") << "" << "bar" << "toto" << "bar/toto";
432 QTest::addRow("localDir+fullPrefix") << "/foo" << "" << "toto" << "/foo/toto";
433 QTest::addRow("localDir+directoryPostfix+fullPrefix") << "/foo" << "bar" << "toto" << "/foobar/toto";
434 #endif
435 }
436
Q_DECLARE_METATYPE(CCDFrameType)437 Q_DECLARE_METATYPE(CCDFrameType)
438
439 void TestPlaceholderPath::testSequenceJobSignature()
440 {
441 #if QT_VERSION < 0x050900
442 QSKIP("Skipping fixture-based test on old QT version.");
443 #else
444 QFETCH(QString, localDir);
445 QFETCH(QString, directoryPostfix);
446 QFETCH(QString, fullPrefix);
447 QFETCH(QString, signature);
448
449 auto job = new Ekos::SequenceJob();
450 job->setLocalDir(localDir);
451 job->setDirectoryPostfix(directoryPostfix);
452 job->setFullPrefix(fullPrefix);
453
454 QCOMPARE(job->getSignature(), signature);
455
456 delete job;
457 #endif
458 }
459
testFullNamingSequence_data()460 void TestPlaceholderPath::testFullNamingSequence_data()
461 {
462 #if QT_VERSION < 0x050900
463 QSKIP("Skipping fixture-based test on old QT version.");
464 #else
465 const QList<const char*> columns =
466 {
467 "Exposure",
468 "Filter",
469 "Type",
470 "Prefix",
471 "RawPrefix",
472 "FilterEnabled",
473 "ExpEnabled",
474 "TimeStampEnabled",
475 "FITSDirectory",
476 "targetName",
477 "batch_mode",
478 "nextSequenceID",
479 "result",
480 };
481 for (const auto &column : columns)
482 {
483 QTest::addColumn<QString>(column);
484 }
485 parseCSV(":/testFullNamingSequence_data.csv", columns);
486 #endif
487 }
488
testFullNamingSequence()489 void TestPlaceholderPath::testFullNamingSequence()
490 {
491 #if QT_VERSION < 0x050900
492 QSKIP("Skipping fixture-based test on old QT version.");
493 #else
494
495 QFETCH(QString, Exposure);
496 QFETCH(QString, Filter);
497 QFETCH(QString, Type);
498 QFETCH(QString, Prefix);
499 QFETCH(QString, RawPrefix);
500 QFETCH(QString, FilterEnabled);
501 QFETCH(QString, ExpEnabled);
502 QFETCH(QString, TimeStampEnabled);
503 QFETCH(QString, FITSDirectory);
504 QFETCH(QString, targetName);
505 QFETCH(QString, batch_mode);
506 QFETCH(QString, nextSequenceID);
507 QFETCH(QString, result);
508
509 XMLEle *root = buildXML(
510 Exposure,
511 Filter,
512 Type,
513 Prefix,
514 RawPrefix,
515 FilterEnabled,
516 ExpEnabled,
517 TimeStampEnabled,
518 FITSDirectory);
519
520 Ekos::SequenceJob job(root);
521 auto placeholderPath = Ekos::PlaceholderPath();
522 // for addJob, targetName should already be sanitized
523 // taken from scheduler.cpp:2491-2495
524 targetName = targetName.replace( QRegularExpression("\\s|/|\\(|\\)|:|\\*|~|\"" ), "_" )
525 // Remove any two or more __
526 .replace( QRegularExpression("_{2,}"), "_")
527 // Remove any _ at the end
528 .replace( QRegularExpression("_$"), "");
529 placeholderPath.addJob(&job, targetName);
530 QString fitsDir, filename;
531 // from sequencejob.cpp:302-303
532 if (job.getLocalDir().isEmpty() == false)
533 fitsDir = job.getLocalDir() + job.getDirectoryPostfix();
534 placeholderPath.generateFilenameOld(".fits", bool(batch_mode.toInt()), &filename, fitsDir, job.getFullPrefix(),
535 nextSequenceID.toInt());
536 //QCOMPARE(filename, result);
537 QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
538 QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
539
540 #endif
541 }
542
testFlexibleNaming_data()543 void TestPlaceholderPath::testFlexibleNaming_data()
544 {
545 #if QT_VERSION < 0x050900
546 QSKIP("Skipping fixture-based test on old QT version.");
547 #else
548 const QList<const char*> columns =
549 {
550 "Exposure",
551 "Filter",
552 "Type",
553 "Prefix",
554 "RawPrefix",
555 "FilterEnabled",
556 "ExpEnabled",
557 "TimeStampEnabled",
558 "seqFilename",
559 "targetName",
560 "batch_mode",
561 "nextSequenceID",
562 "format",
563 "result",
564 };
565 for (const auto &column : columns)
566 {
567 QTest::addColumn<QString>(column);
568 }
569 QTest::addRow("infinite") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/%f_100x30s_RGB.esq"
570 << "" << "1" << "" << "%f" << "^%f_100x30s_RGB\\.fits$";
571 QTest::addRow("f") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
572 "1" << "" << "%f" << "^100x30s_RGB\\.fits$";
573 QTest::addRow("p") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
574 "1" << "" << "%p" << "^/home/user/Images/NGC7635\\.fits$";
575 QTest::addRow("p1") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
576 "1" << "" << "%p1" << "^/home/user/Images/NGC7635\\.fits$";
577 QTest::addRow("p2") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
578 "1" << "" << "%p2" << "^/home/user/Images\\.fits$";
579 QTest::addRow("p3") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
580 "1" << "" << "%p3" << "^/home/user\\.fits$";
581 QTest::addRow("p4") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
582 "1" << "" << "%p4" << "^/home\\.fits$";
583 QTest::addRow("d") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
584 "1" << "" << "%d" << "^NGC7635\\.fits$";
585 QTest::addRow("d1") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
586 "1" << "" << "%d1" << "^NGC7635\\.fits$";
587 QTest::addRow("d2") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
588 "1" << "" << "%d2" << "^Images\\.fits$";
589 QTest::addRow("d3") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
590 "1" << "" << "%d3" << "^user\\.fits$";
591 QTest::addRow("d4") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
592 "1" << "" << "%d4" << "^home\\.fits$";
593
594 QTest::addRow("t") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "target" << "" << ""
595 << "%t" << "^/tmp/kstars/target\\.fits$";
596 QTest::addRow("T") << "" << "" << "Light" << "" << "" << "" << "" << "" << "" << "" << "" << ""
597 << "%T" << "^/tmp/kstars/Light\\.fits$";
598 QTest::addRow("F") << "" << "sobel" << "" << "prefix" << "" << "1" << "" << "" << "" << "" << "" << ""
599 << "%F" << "^/tmp/kstars/sobel\\.fits$";
600 QTest::addRow("e") << "0.001" << "" << "" << "prefix" << "" << "" << "1" << "" << "" << "" << "" << ""
601 << "%e" << "^/tmp/kstars/0.001_secs\\.fits$";
602 QTest::addRow("D") << "" << "" << "" << "prefix" << "" << "" << "" << "1" << "" << "" << "" << ""
603 << "%D" << "^/tmp/kstars/\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}\\.fits$";
604 QTest::addRow("s") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1"
605 << "%s" << "^/tmp/kstars/1\\.fits$";
606 QTest::addRow("s1") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1"
607 << "%s1" << "^/tmp/kstars/1\\.fits$";
608 QTest::addRow("s2") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1"
609 << "%s2" << "^/tmp/kstars/01\\.fits$";
610 QTest::addRow("s3") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1"
611 << "%s3" << "^/tmp/kstars/001\\.fits$";
612 QTest::addRow("s4") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1"
613 << "%s4" << "^/tmp/kstars/0001\\.fits$";
614
615 QTest::addRow("_s") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1" << "_%s" <<
616 "^/tmp/kstars/_1\\.fits$";
617 QTest::addRow("unknown1") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "%b" <<
618 "^/tmp/kstars/%b\\.fits$";
619 QTest::addRow("unknown2") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "%f_%a_%t" <<
620 "^/tmp/kstars/%a_\\.fits$";
621
622 parseCSV(":/testFlexibleNaming_data.csv", columns);
623 #endif
624 }
625
testFlexibleNaming()626 void TestPlaceholderPath::testFlexibleNaming()
627 {
628 #if QT_VERSION < 0x050900
629 QSKIP("Skipping fixture-based test on old QT version.");
630 #else
631 QFETCH(QString, Exposure);
632 QFETCH(QString, Filter);
633 QFETCH(QString, Type);
634 QFETCH(QString, Prefix);
635 QFETCH(QString, RawPrefix);
636 QFETCH(QString, FilterEnabled);
637 QFETCH(QString, ExpEnabled);
638 QFETCH(QString, TimeStampEnabled);
639 QFETCH(QString, seqFilename);
640 QFETCH(QString, targetName);
641 QFETCH(QString, batch_mode);
642 QFETCH(QString, nextSequenceID);
643 QFETCH(QString, format);
644 QFETCH(QString, result);
645
646 XMLEle *root = buildXML(
647 Exposure,
648 Filter,
649 Type,
650 Prefix,
651 RawPrefix,
652 FilterEnabled,
653 ExpEnabled,
654 TimeStampEnabled,
655 "");
656
657 Ekos::SequenceJob job(root);
658 auto placeholderPath = Ekos::PlaceholderPath(seqFilename);
659 QString filename;
660 bool bm = bool(batch_mode.toInt());
661 int i = nextSequenceID.toInt();
662 placeholderPath.generateFilename(format, job, targetName, bm, i, ".fits", &filename);
663 QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
664 QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
665
666 job.setTargetName(targetName);
667 placeholderPath.setGenerateFilenameSettings(job);
668 placeholderPath.generateFilename(format, job.isTimestampPrefixEnabled(), bm, i, ".fits", &filename);
669 QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
670 QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
671 #endif
672 }
673
testFlexibleNamingChangeBehavior_data()674 void TestPlaceholderPath::testFlexibleNamingChangeBehavior_data()
675 {
676 #if QT_VERSION < 0x050900
677 QSKIP("Skipping fixture-based test on old QT version.");
678 #else
679 const QList<const char*> columns =
680 {
681 "Exposure",
682 "Filter",
683 "Type",
684 "Prefix",
685 "RawPrefix",
686 "FilterEnabled",
687 "ExpEnabled",
688 "TimeStampEnabled",
689 "seqFilename",
690 "targetName",
691 "batch_mode",
692 "nextSequenceID",
693 "format",
694 "old_result",
695 "new_result",
696 };
697 for (const auto &column : columns)
698 {
699 QTest::addColumn<QString>(column);
700 }
701 parseCSV(":/testFlexibleNamingChangeBehavior_data.csv", columns);
702 #endif
703 }
704
testFlexibleNamingChangeBehavior()705 void TestPlaceholderPath::testFlexibleNamingChangeBehavior()
706 {
707 #if QT_VERSION < 0x050900
708 QSKIP("Skipping fixture-based test on old QT version.");
709 #else
710 QFETCH(QString, Exposure);
711 QFETCH(QString, Filter);
712 QFETCH(QString, Type);
713 QFETCH(QString, Prefix);
714 QFETCH(QString, RawPrefix);
715 QFETCH(QString, FilterEnabled);
716 QFETCH(QString, ExpEnabled);
717 QFETCH(QString, TimeStampEnabled);
718 QFETCH(QString, seqFilename);
719 QFETCH(QString, targetName);
720 QFETCH(QString, batch_mode);
721 QFETCH(QString, nextSequenceID);
722 QFETCH(QString, format);
723 QFETCH(QString, old_result);
724 QFETCH(QString, new_result);
725
726 XMLEle *root = buildXML(
727 Exposure,
728 Filter,
729 Type,
730 Prefix,
731 RawPrefix,
732 FilterEnabled,
733 ExpEnabled,
734 TimeStampEnabled,
735 "");
736
737 Ekos::SequenceJob job(root);
738 auto placeholderPath = Ekos::PlaceholderPath(seqFilename);
739 QString filename;
740 bool bm = bool(batch_mode.toInt());
741 int i = nextSequenceID.toInt();
742 placeholderPath.generateFilename(format, job, targetName, bm, i, ".fits", &filename);
743 QEXPECT_FAIL("", "original filename had __ or // or /_ that are now removed", Continue);
744 QVERIFY2(QRegularExpression(old_result).match(filename).hasMatch(),
745 QString("\nNot Expected: %1\nObtained: %2\n").arg(old_result, filename).toStdString().c_str());
746 QVERIFY2(QRegularExpression(new_result).match(filename).hasMatch(),
747 QString("\nExpected: %1\nObtained: %2\n").arg(new_result, filename).toStdString().c_str());
748
749 job.setTargetName(targetName);
750 placeholderPath.setGenerateFilenameSettings(job);
751 placeholderPath.generateFilename(format, job.isTimestampPrefixEnabled(), bm, i, ".fits", &filename);
752 QEXPECT_FAIL("", "original filename had __ or // or /_ that are now removed", Continue);
753 QVERIFY2(QRegularExpression(old_result).match(filename).hasMatch(),
754 QString("\nNot Expected: %1\nObtained: %2\n").arg(old_result, filename).toStdString().c_str());
755 QVERIFY2(QRegularExpression(new_result).match(filename).hasMatch(),
756 QString("\nExpected: %1\nObtained: %2\n").arg(new_result, filename).toStdString().c_str());
757 #endif
758 }
759
testRemainingPlaceholders_data()760 void TestPlaceholderPath::testRemainingPlaceholders_data()
761 {
762 #if QT_VERSION < 0x050900
763 QSKIP("Skipping fixture-based test on old QT version.");
764 #else
765 QTest::addColumn<QString>("Filename");
766 QTest::addColumn<QStringList>("Result");
767 QTest::addRow("0") << "test.fits" << QStringList();
768 QTest::addRow("1") << "%f_test.fits" << QStringList({"%f"});
769 QTest::addRow("2") << "%p/%f_test.fits" << QStringList({"%p", "%f"});
770 #endif
771 }
772
testRemainingPlaceholders()773 void TestPlaceholderPath::testRemainingPlaceholders()
774 {
775 #if QT_VERSION < 0x050900
776 QSKIP("Skipping fixture-based test on old QT version.");
777 #else
778 QFETCH(QString, Filename);
779 QFETCH(QStringList, Result);
780
781 auto remainingPlaceholders = Ekos::PlaceholderPath::remainingPlaceholders(Filename);
782 QCOMPARE(remainingPlaceholders, Result);
783 #endif
784 }
785 QTEST_GUILESS_MAIN(TestPlaceholderPath)
786