1 /* 2 * Cppcheck - A tool for static C/C++ code analysis 3 * Copyright (C) 2007-2021 Cppcheck team. 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 3 of the License, or 8 * (at your option) 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 this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "settings.h" 20 #include "testsuite.h" 21 #include "threadexecutor.h" 22 23 #include <map> 24 #include <string> 25 #include <utility> 26 27 class TestThreadExecutor : public TestFixture { 28 public: TestThreadExecutor()29 TestThreadExecutor() : TestFixture("TestThreadExecutor") {} 30 31 private: 32 Settings settings; 33 34 /** 35 * Execute check using n jobs for y files which are have 36 * identical data, given within data. 37 */ check(unsigned int jobs,int files,int result,const std::string & data)38 void check(unsigned int jobs, int files, int result, const std::string &data) { 39 errout.str(""); 40 output.str(""); 41 if (!ThreadExecutor::isEnabled()) { 42 // Skip this check on systems which don't use this feature 43 return; 44 } 45 46 std::map<std::string, std::size_t> filemap; 47 for (int i = 1; i <= files; ++i) { 48 std::ostringstream oss; 49 oss << "file_" << i << ".cpp"; 50 filemap[oss.str()] = 1; 51 } 52 53 settings.jobs = jobs; 54 ThreadExecutor executor(filemap, settings, *this); 55 for (std::map<std::string, std::size_t>::const_iterator i = filemap.begin(); i != filemap.end(); ++i) 56 executor.addFileContent(i->first, data); 57 58 ASSERT_EQUALS(result, executor.check()); 59 } 60 run()61 void run() OVERRIDE { 62 LOAD_LIB_2(settings.library, "std.cfg"); 63 64 TEST_CASE(deadlock_with_many_errors); 65 TEST_CASE(many_threads); 66 TEST_CASE(no_errors_more_files); 67 TEST_CASE(no_errors_less_files); 68 TEST_CASE(no_errors_equal_amount_files); 69 TEST_CASE(one_error_less_files); 70 TEST_CASE(one_error_several_files); 71 } 72 deadlock_with_many_errors()73 void deadlock_with_many_errors() { 74 std::ostringstream oss; 75 oss << "int main()\n" 76 << "{\n"; 77 for (int i = 0; i < 500; i++) 78 oss << " {char *a = malloc(10);}\n"; 79 80 oss << " return 0;\n" 81 << "}\n"; 82 check(2, 3, 3, oss.str()); 83 } 84 many_threads()85 void many_threads() { 86 check(16, 100, 100, 87 "int main()\n" 88 "{\n" 89 " char *a = malloc(10);\n" 90 " return 0;\n" 91 "}"); 92 } 93 no_errors_more_files()94 void no_errors_more_files() { 95 check(2, 3, 0, 96 "int main()\n" 97 "{\n" 98 " return 0;\n" 99 "}"); 100 } 101 no_errors_less_files()102 void no_errors_less_files() { 103 check(2, 1, 0, 104 "int main()\n" 105 "{\n" 106 " return 0;\n" 107 "}"); 108 } 109 no_errors_equal_amount_files()110 void no_errors_equal_amount_files() { 111 check(2, 2, 0, 112 "int main()\n" 113 "{\n" 114 " return 0;\n" 115 "}"); 116 } 117 one_error_less_files()118 void one_error_less_files() { 119 check(2, 1, 1, 120 "int main()\n" 121 "{\n" 122 " {char *a = malloc(10);}\n" 123 " return 0;\n" 124 "}"); 125 } 126 one_error_several_files()127 void one_error_several_files() { 128 check(2, 20, 20, 129 "int main()\n" 130 "{\n" 131 " {char *a = malloc(10);}\n" 132 " return 0;\n" 133 "}"); 134 } 135 }; 136 137 REGISTER_TEST(TestThreadExecutor) 138