Merge pull request #4676 from jmarshallnz/dont_set_scraper_on_tvshow_on_nfo
[vuplus_xbmc] / xbmc / test / TestUtils.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "TestUtils.h"
22 #include "Util.h"
23 #include "filesystem/File.h"
24 #include "filesystem/SpecialProtocol.h"
25 #include "utils/StringUtils.h"
26
27 #ifdef TARGET_WINDOWS
28 #include <windows.h>
29 #else
30 #include <cstdlib>
31 #include <climits>
32 #include <ctime>
33 #endif
34
35 class CTempFile : public XFILE::CFile
36 {
37 public:
38   CTempFile(){};
39   ~CTempFile()
40   {
41     Delete();
42   }
43   bool Create(const CStdString &suffix)
44   {
45     char tmp[MAX_PATH];
46     int fd;
47
48     m_ptempFileDirectory = CSpecialProtocol::TranslatePath("special://temp/");
49     m_ptempFilePath = m_ptempFileDirectory + "xbmctempfileXXXXXX";
50     m_ptempFilePath += suffix;
51     if (m_ptempFilePath.length() >= MAX_PATH)
52     {
53       m_ptempFilePath = "";
54       return false;
55     }
56     strcpy(tmp, m_ptempFilePath.c_str());
57
58 #ifdef TARGET_WINDOWS
59     if (!GetTempFileName(CSpecialProtocol::TranslatePath("special://temp/"),
60                          "xbmctempfile", 0, tmp))
61     {
62       m_ptempFilePath = "";
63       return false;
64     }
65     m_ptempFilePath = tmp;
66 #else
67     if ((fd = mkstemps(tmp, suffix.length())) < 0)
68     {
69       m_ptempFilePath = "";
70       return false;
71     }
72     close(fd);
73     m_ptempFilePath = tmp;
74 #endif
75
76     OpenForWrite(m_ptempFilePath.c_str(), true);
77     return true;
78   }
79   bool Delete()
80   {
81     Close();
82     return CFile::Delete(m_ptempFilePath);
83   };
84   CStdString getTempFilePath() const
85   {
86     return m_ptempFilePath;
87   }
88   CStdString getTempFileDirectory() const
89   {
90     return m_ptempFileDirectory;
91   }
92 private:
93   CStdString m_ptempFilePath;
94   CStdString m_ptempFileDirectory;
95 };
96
97 CXBMCTestUtils::CXBMCTestUtils()
98 {
99   probability = 0.01;
100 }
101
102 CXBMCTestUtils &CXBMCTestUtils::Instance()
103 {
104   static CXBMCTestUtils instance;
105   return instance;
106 }
107
108 CStdString CXBMCTestUtils::ReferenceFilePath(CStdString const& path)
109 {
110   return CSpecialProtocol::TranslatePath("special://xbmc") + path;
111 }
112
113 bool CXBMCTestUtils::SetReferenceFileBasePath()
114 {
115   CStdString xbmcPath;
116   CUtil::GetHomePath(xbmcPath);
117   if (xbmcPath.empty())
118     return false;
119
120   /* Set xbmc path and xbmcbin path */
121   CSpecialProtocol::SetXBMCPath(xbmcPath);
122   CSpecialProtocol::SetXBMCBinPath(xbmcPath);
123
124   return true;
125 }
126
127 XFILE::CFile *CXBMCTestUtils::CreateTempFile(CStdString const& suffix)
128 {
129   CTempFile *f = new CTempFile();
130   if (f->Create(suffix))
131     return f;
132   delete f;
133   return NULL;
134 }
135
136 bool CXBMCTestUtils::DeleteTempFile(XFILE::CFile *tempfile)
137 {
138   if (!tempfile)
139     return true;
140   CTempFile *f = static_cast<CTempFile*>(tempfile);
141   bool retval = f->Delete();
142   delete f;
143   return retval;
144 }
145
146 CStdString CXBMCTestUtils::TempFilePath(XFILE::CFile const* const tempfile)
147 {
148   if (!tempfile)
149     return "";
150   CTempFile const* const f = static_cast<CTempFile const* const>(tempfile);
151   return f->getTempFilePath();
152 }
153
154 CStdString CXBMCTestUtils::TempFileDirectory(XFILE::CFile const* const tempfile)
155 {
156   if (!tempfile)
157     return "";
158   CTempFile const* const f = static_cast<CTempFile const* const>(tempfile);
159   return f->getTempFileDirectory();
160 }
161
162 XFILE::CFile *CXBMCTestUtils::CreateCorruptedFile(CStdString const& strFileName,
163   CStdString const& suffix)
164 {
165   XFILE::CFile inputfile, *tmpfile = CreateTempFile(suffix);
166   unsigned char buf[20], tmpchar;
167   unsigned int size, i;
168
169   if (tmpfile && inputfile.Open(strFileName))
170   {
171     srand(time(NULL));
172     while ((size = inputfile.Read(buf, sizeof(buf))) > 0)
173     {
174       for (i = 0; i < size; i++)
175       {
176         if ((rand() % RAND_MAX) < (probability * RAND_MAX))
177         {
178           tmpchar = buf[i];
179           do
180           {
181             buf[i] = (rand() % 256);
182           } while (buf[i] == tmpchar);
183         }
184       }
185       if (tmpfile->Write(buf, size) < 0)
186       {
187         inputfile.Close();
188         tmpfile->Close();
189         DeleteTempFile(tmpfile);
190         return NULL;
191       }
192     }
193     inputfile.Close();
194     tmpfile->Close();
195     return tmpfile;
196   }
197   delete tmpfile;
198   return NULL;
199 }
200
201
202 std::vector<CStdString> &CXBMCTestUtils::getTestFileFactoryReadUrls()
203 {
204   return TestFileFactoryReadUrls;
205 }
206
207 std::vector<CStdString> &CXBMCTestUtils::getTestFileFactoryWriteUrls()
208 {
209   return TestFileFactoryWriteUrls;
210 }
211
212 CStdString &CXBMCTestUtils::getTestFileFactoryWriteInputFile()
213 {
214   return TestFileFactoryWriteInputFile;
215 }
216
217 void CXBMCTestUtils::setTestFileFactoryWriteInputFile(CStdString const& file)
218 {
219   TestFileFactoryWriteInputFile = file;
220 }
221
222 std::vector<CStdString> &CXBMCTestUtils::getAdvancedSettingsFiles()
223 {
224   return AdvancedSettingsFiles;
225 }
226
227 std::vector<CStdString> &CXBMCTestUtils::getGUISettingsFiles()
228 {
229   return GUISettingsFiles;
230 }
231
232 static const char usage[] =
233 "XBMC Test Suite\n"
234 "Usage: xbmc-test [options]\n"
235 "\n"
236 "The following options are recognized by the xbmc-test program.\n"
237 "\n"
238 "  --add-testfilefactory-readurl [URL]\n"
239 "    Add a url to be used int the TestFileFactory read tests.\n"
240 "\n"
241 "  --add-testfilefactory-readurls [URLS]\n"
242 "    Add multiple urls from a ',' delimited string of urls to be used\n"
243 "    in the TestFileFactory read tests.\n"
244 "\n"
245 "  --add-testfilefactory-writeurl [URL]\n"
246 "    Add a url to be used int the TestFileFactory write tests.\n"
247 "\n"
248 "  --add-testfilefactory-writeurls [URLS]\n"
249 "    Add multiple urls from a ',' delimited string of urls to be used\n"
250 "    in the TestFileFactory write tests.\n"
251 "\n"
252 "  --set-testfilefactory-writeinputfile [FILE]\n"
253 "    Set the path to the input file used in the TestFileFactory write tests.\n"
254 "\n"
255 "  --add-advancedsettings-file [FILE]\n"
256 "    Add an advanced settings file to be loaded in test cases that use them.\n"
257 "\n"
258 "  --add-advancedsettings-files [FILES]\n"
259 "    Add multiple advanced settings files from a ',' delimited string of\n"
260 "    files to be loaded in test cases that use them.\n"
261 "\n"
262 "  --add-guisettings-file [FILE]\n"
263 "    Add a GUI settings file to be loaded in test cases that use them.\n"
264 "\n"
265 "  --add-guisettings-files [FILES]\n"
266 "    Add multiple GUI settings files from a ',' delimited string of\n"
267 "    files to be loaded in test cases that use them.\n"
268 "\n"
269 "  --set-probability [PROBABILITY]\n"
270 "    Set the probability variable used by the file corrupting functions.\n"
271 "    The variable should be a double type from 0.0 to 1.0. Values given\n"
272 "    less than 0.0 are treated as 0.0. Values greater than 1.0 are treated\n"
273 "    as 1.0. The default probability is 0.01.\n"
274 ;
275
276 void CXBMCTestUtils::ParseArgs(int argc, char **argv)
277 {
278   int i;
279   CStdString arg;
280   for (i = 1; i < argc; i++)
281   {
282     arg = argv[i];
283     if (arg == "--add-testfilefactory-readurl")
284     {
285       TestFileFactoryReadUrls.push_back(argv[++i]);
286     }
287     else if (arg == "--add-testfilefactory-readurls")
288     {
289       arg = argv[++i];
290       std::vector<std::string> urls = StringUtils::Split(arg, ",");
291       std::vector<std::string>::iterator it;
292       for (it = urls.begin(); it < urls.end(); it++)
293         TestFileFactoryReadUrls.push_back(*it);
294     }
295     else if (arg == "--add-testfilefactory-writeurl")
296     {
297       TestFileFactoryWriteUrls.push_back(argv[++i]);
298     }
299     else if (arg == "--add-testfilefactory-writeurls")
300     {
301       arg = argv[++i];
302       std::vector<std::string> urls = StringUtils::Split(arg, ",");
303       std::vector<std::string>::iterator it;
304       for (it = urls.begin(); it < urls.end(); it++)
305         TestFileFactoryWriteUrls.push_back(*it);
306     }
307     else if (arg == "--set-testfilefactory-writeinputfile")
308     {
309       TestFileFactoryWriteInputFile = argv[++i];
310     }
311     else if (arg == "--add-advancedsettings-file")
312     {
313       AdvancedSettingsFiles.push_back(argv[++i]);
314     }
315     else if (arg == "--add-advancedsettings-files")
316     {
317       arg = argv[++i];
318       std::vector<std::string> urls = StringUtils::Split(arg, ",");
319       std::vector<std::string>::iterator it;
320       for (it = urls.begin(); it < urls.end(); it++)
321         AdvancedSettingsFiles.push_back(*it);
322     }
323     else if (arg == "--add-guisettings-file")
324     {
325       GUISettingsFiles.push_back(argv[++i]);
326     }
327     else if (arg == "--add-guisettings-files")
328     {
329       arg = argv[++i];
330       std::vector<std::string> urls = StringUtils::Split(arg, ",");
331       std::vector<std::string>::iterator it;
332       for (it = urls.begin(); it < urls.end(); it++)
333         GUISettingsFiles.push_back(*it);
334     }
335     else if (arg == "--set-probability")
336     {
337       probability = atof(argv[++i]);
338       if (probability < 0.0)
339         probability = 0.0;
340       else if (probability > 1.0)
341         probability = 1.0;
342     }
343     else
344     {
345       std::cerr << usage;
346       exit(EXIT_FAILURE);
347     }
348   }
349 }
350
351 std::string CXBMCTestUtils::getNewLineCharacters() const
352 {
353 #ifdef TARGET_WINDOWS
354   return "\r\n";
355 #else
356   return "\n";
357 #endif
358 }