ssu
Loading...
Searching...
No Matches
upgradetesthelper.cpp
Go to the documentation of this file.
1
7
8#include "upgradetesthelper.h"
9
10#include <QtCore/QBuffer>
11#include <QtCore/QDebug>
12#include <QtCore/qmath.h>
13#include <QtCore/QTemporaryFile>
14#include <QtCore/QTextStream>
15
17
89
90QList<UpgradeTestHelper::TestCase> UpgradeTestHelper::readRecipe(QIODevice *recipe)
91{
92 QList<TestCase> testCases;
93
94 while (!recipe->atEnd()) {
95 const QString line = recipe->readLine().trimmed();
96 if (line.startsWith('#') || line.isEmpty())
97 continue;
98 const QStringList splitted = line.split(':');
99 Q_ASSERT_X(splitted.count() == 3, Q_FUNC_INFO,
100 qPrintable(QString("Inalid recipe line '%1'").arg(line)));
101 testCases.append(TestCase(splitted.at(0), splitted.at(1), splitted.at(2)));
102 }
103
104 return testCases;
105}
106
107void UpgradeTestHelper::fillSettings(QSettings *settings, const QList<TestCase> &testCases)
108{
109 settings->setValue("configVersion", CurrentVersion);
110
111 foreach (const QString &group, groups()) {
112 settings->beginGroup(group);
113
114 foreach (const TestCase &testCase, testCases) {
115 if (!testCase.current().isEmpty()) {
116 settings->setValue(testCase.key(), testCase.current());
117 }
118 }
119
120 settings->endGroup();
121 }
122
123 settings->sync();
124}
125
126void UpgradeTestHelper::fillDefaultSettings(QSettings *defaultSettings, const QList<TestCase>
127 &testCases)
128{
129 defaultSettings->setValue("configVersion", HistoryLength);
130
131 QHash<QString, QString> lastSetValue; // for the (K)eep action; no need to qualify with group
132
133 for (int revision = 1; revision <= HistoryLength; ++revision) {
134 defaultSettings->beginGroup(QString::number(revision));
135
136 QStringList keysToRemove;
137
138 foreach (const QString &group, groups()) {
139 defaultSettings->beginGroup(group);
140
141 foreach (const TestCase &testCase, testCases) {
142 switch (testCase.history().at(revision - 1).toLatin1()) {
143 case 'S': // (S)et value
144 lastSetValue[testCase.key()] = QString("v%1-default").arg(revision);
145 defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]);
146 break;
147
148 case 'K': // (K)eep value
149 Q_ASSERT_X(!lastSetValue[testCase.key()].isEmpty(), Q_FUNC_INFO,
150 qPrintable(QString("Inalid TestCase::history: '%1'").arg(testCase.history())));
151 defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]);
152 break;
153
154 case 'R': // (R)emove key
155 keysToRemove.append((group.isEmpty() ? group : group + "/") + testCase.key());
156 lastSetValue.remove(testCase.key());
157 break;
158
159 case 'N': // (N)oop
160 break;
161
162 default:
163 Q_ASSERT_X(false, Q_FUNC_INFO, qPrintable(QString(
164 "Inalid TestCase::history: '%1': invalid command-code '%2'")
165 .arg(testCase.history())
166 .arg(testCase.history().at(revision - 1))));
167 }
168
169 }
170
171 defaultSettings->endGroup();
172 }
173
174 if (!keysToRemove.isEmpty()) {
175 defaultSettings->setValue("cmd-remove", keysToRemove);
176 }
177
178 defaultSettings->endGroup();
179 }
180
181 defaultSettings->sync();
182}
183
184bool UpgradeTestHelper::generateSnapshotRecipe(QTextStream *out)
185{
186 const QString actions = "SKRN";
187
188 QBuffer buf;
189 buf.open(QIODevice::ReadWrite);
190 QTextStream stream(&buf);
191
192 // for all "valid" variations of the letters "SKRN" of length HistoryLength
193 for (int i = 0; i < qPow(actions.count(), HistoryLength); ++i) {
194 QString history = QString::number(i, actions.count());
195 // Left pad to HistoryLength
196 history.prepend(QString(HistoryLength - history.length(), '0'));
197 for (int revision = 0; revision < history.length(); ++revision) {
198 history.replace(revision, 1, actions.at(history.at(revision).digitValue()));
199 }
200
201 static const QRegExp invalidSequence("(^[^S]*K|R[^S]*K|^R)");
202 if (history.contains(invalidSequence)) {
203 continue;
204 }
205
206 for (int revision = 0; revision < HistoryLength; ++revision) {
207 stream << history << QString(":v%1-default:\n").arg(revision);
208 }
209
210 stream << history << ":custom:\n";
211 }
212
213 stream.flush();
214
215 // Read recipe
216 buf.seek(0);
217 QList<TestCase> testCases = readRecipe(&buf);
218
219 // Generate settings file according to recipe
220 QTemporaryFile settingsFile;
221 if (!settingsFile.open()) {
222 return false;
223 }
224
225 QSettings settings(settingsFile.fileName(), QSettings::IniFormat);
226
227 fillSettings(&settings, testCases);
228
229 // Generate defaults file according to recipe
230 QTemporaryFile defaultSettingsFile;
231 if (!defaultSettingsFile.open()) {
232 return false;
233 }
234
235 QSettings defaultSettings(defaultSettingsFile.fileName(), QSettings::IniFormat);
236
237 fillDefaultSettings(&defaultSettings, testCases);
238
239 // Parse settings -- do upgrade
240 SsuSettings ssuSettings(settingsFile.fileName(), QSettings::IniFormat,
241 defaultSettingsFile.fileName());
242
243 // Output recipe
244 foreach (const UpgradeTestHelper::TestCase &testCase, testCases) {
245 const QString expected = ssuSettings.contains(testCase.key())
246 ? ssuSettings.value(testCase.key()).toString()
247 : "@NOTSET@";
248 *out << QString("%1:%2:%3\n")
249 .arg(testCase.history())
250 .arg(testCase.current())
251 .arg(expected);
252 }
253
254 return true;
255}
256
257QStringList UpgradeTestHelper::groups()
258{
259 static const QStringList groups = QStringList() << "" /* General */ << "groupA";
260 return groups;
261}