test/Suite.cc

Code
Comments
Other
Rev Date Author Line
596 14 Apr 08 peter 1 // $Id$
596 14 Apr 08 peter 2
596 14 Apr 08 peter 3 /*
978 12 Dec 09 peter 4   Copyright (C) 2008 Jari Häkkinen, Peter Johansson
1635 30 Mar 23 peter 5   Copyright (C) 2009, 2010, 2012, 2023 Peter Johansson
596 14 Apr 08 peter 6
687 04 Aug 08 peter 7   This file is part of the yat library, http://dev.thep.lu.se/yat
596 14 Apr 08 peter 8
596 14 Apr 08 peter 9   The yat library is free software; you can redistribute it and/or
596 14 Apr 08 peter 10   modify it under the terms of the GNU General Public License as
693 11 Sep 08 jari 11   published by the Free Software Foundation; either version 3 of the
596 14 Apr 08 peter 12   License, or (at your option) any later version.
596 14 Apr 08 peter 13
596 14 Apr 08 peter 14   The yat library is distributed in the hope that it will be useful,
596 14 Apr 08 peter 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
596 14 Apr 08 peter 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
596 14 Apr 08 peter 17   General Public License for more details.
596 14 Apr 08 peter 18
596 14 Apr 08 peter 19   You should have received a copy of the GNU General Public License
693 11 Sep 08 jari 20   along with svndigest. If not, see <http://www.gnu.org/licenses/>.
596 14 Apr 08 peter 21 */
596 14 Apr 08 peter 22
744 08 Jan 09 peter 23 #include <config.h>
744 08 Jan 09 peter 24
596 14 Apr 08 peter 25 #include "Suite.h"
1525 01 Oct 12 peter 26 // include from topdir to allow VPATH build
1525 01 Oct 12 peter 27 #include "test/environment.h"
596 14 Apr 08 peter 28
1119 04 Jul 10 peter 29 #include "lib/Stats.h"
1119 04 Jul 10 peter 30 #include "lib/StatsCollection.h"
1119 04 Jul 10 peter 31 #include "lib/utility.h"
744 08 Jan 09 peter 32
1675 26 Aug 23 peter 33 #include <yat/utility/utility.h>
1675 26 Aug 23 peter 34
803 10 Jul 09 peter 35 #include <algorithm>
1478 29 May 12 peter 36 #include <cstdlib>
744 08 Jan 09 peter 37 #include <fstream>
744 08 Jan 09 peter 38 #include <iostream>
803 10 Jul 09 peter 39 #include <iterator>
1478 29 May 12 peter 40 #include <sstream>
1478 29 May 12 peter 41 #include <stdexcept>
596 14 Apr 08 peter 42 #include <string>
596 14 Apr 08 peter 43
596 14 Apr 08 peter 44 namespace theplu {
596 14 Apr 08 peter 45 namespace svndigest {
596 14 Apr 08 peter 46 namespace test {
596 14 Apr 08 peter 47
744 08 Jan 09 peter 48   Suite::Suite(int argc, char* argv[], bool need_test_repo)
1044 27 Mar 10 peter 49     : ok_(true)
744 08 Jan 09 peter 50   {
1675 26 Aug 23 peter 51     yat::utility::chdir(abs_builddir());
1675 26 Aug 23 peter 52     std::string test_dir =
1675 26 Aug 23 peter 53       concatenate_path("testSubDir", yat::utility::basename(argv[0]));
1675 26 Aug 23 peter 54     yat::utility::mkdir_p(test_dir);
1675 26 Aug 23 peter 55     yat::utility::chdir(test_dir);
1104 15 Jun 10 peter 56     out() << "running `" << argv[0] << "' in `" << test_dir << "'\n";
744 08 Jan 09 peter 57     if (need_test_repo) {
744 08 Jan 09 peter 58       bool have_test_repo=false;
744 08 Jan 09 peter 59       #ifdef HAVE_TEST_REPO
744 08 Jan 09 peter 60       have_test_repo=true;
744 08 Jan 09 peter 61       #endif
744 08 Jan 09 peter 62       if (!have_test_repo) {
744 08 Jan 09 peter 63         out() << "Skipping test because test repository is not available\n";
1182 25 Aug 10 peter 64         exit (EXIT_SKIP);
744 08 Jan 09 peter 65       }
744 08 Jan 09 peter 66       update_test_wc();
744 08 Jan 09 peter 67     }
744 08 Jan 09 peter 68
744 08 Jan 09 peter 69   }
744 08 Jan 09 peter 70
744 08 Jan 09 peter 71
744 08 Jan 09 peter 72   Suite::~Suite(void)
744 08 Jan 09 peter 73   {
744 08 Jan 09 peter 74   }
744 08 Jan 09 peter 75
1611 12 Feb 23 peter 76
744 08 Jan 09 peter 77   bool Suite::add(bool b)
744 08 Jan 09 peter 78   {
744 08 Jan 09 peter 79     ok_ = ok_ && b;
744 08 Jan 09 peter 80     return b;
744 08 Jan 09 peter 81   }
744 08 Jan 09 peter 82
744 08 Jan 09 peter 83
1162 13 Aug 10 peter 84   int Suite::exit_status(void) const
1162 13 Aug 10 peter 85   {
1162 13 Aug 10 peter 86     int value = EXIT_FAILURE;
1162 13 Aug 10 peter 87     if (ok()) {
1611 12 Feb 23 peter 88       value = EXIT_SUCCESS;
1162 13 Aug 10 peter 89     }
1162 13 Aug 10 peter 90     out() << "exit status: " << value << "\n";
1162 13 Aug 10 peter 91     return value;
1162 13 Aug 10 peter 92   }
1162 13 Aug 10 peter 93
1162 13 Aug 10 peter 94
744 08 Jan 09 peter 95   bool Suite::ok(void) const
744 08 Jan 09 peter 96   {
744 08 Jan 09 peter 97     return ok_;
744 08 Jan 09 peter 98   }
744 08 Jan 09 peter 99
744 08 Jan 09 peter 100
744 08 Jan 09 peter 101   std::ostream& Suite::out(void) const
744 08 Jan 09 peter 102   {
1044 27 Mar 10 peter 103     return std::cout;
744 08 Jan 09 peter 104   }
744 08 Jan 09 peter 105
744 08 Jan 09 peter 106
803 10 Jul 09 peter 107   bool check_all(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 108   {
1611 12 Feb 23 peter 109     for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 110                    LineTypeParser::other, LineTypeParser::total}) {
803 10 Jul 09 peter 111       for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
803 10 Jul 09 peter 112         size_t all = 0;
803 10 Jul 09 peter 113         for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 114              a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 115           all += stats(lt, *a, rev);
803 10 Jul 09 peter 116         }
803 10 Jul 09 peter 117         if (all!=stats(lt, "all", rev)) {
803 10 Jul 09 peter 118           suite.out() << "error: check_all\n"
803 10 Jul 09 peter 119                       << " lt = " << lt << "\n"
803 10 Jul 09 peter 120                       << " rev = " << rev << "\n"
803 10 Jul 09 peter 121                       << " all = " << all << "\n"
803 10 Jul 09 peter 122                       << " stats = " << stats(lt, "all", rev) << "\n";
803 10 Jul 09 peter 123           for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 124                a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 125             suite.out() << *a << " " << stats(lt, *a, rev) << "\n";
803 10 Jul 09 peter 126           }
803 10 Jul 09 peter 127           return false;
803 10 Jul 09 peter 128         }
803 10 Jul 09 peter 129       }
803 10 Jul 09 peter 130     }
803 10 Jul 09 peter 131     return true;
803 10 Jul 09 peter 132   }
803 10 Jul 09 peter 133
1611 12 Feb 23 peter 134
803 10 Jul 09 peter 135   bool check_total(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 136   {
803 10 Jul 09 peter 137     for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
803 10 Jul 09 peter 138       for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 139            a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 140         unsigned int total=0;
1611 12 Feb 23 peter 141         for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 142                        LineTypeParser::other}) {
803 10 Jul 09 peter 143           total += stats(lt, *a, rev);
803 10 Jul 09 peter 144         }
803 10 Jul 09 peter 145         unsigned int total2=stats(LineTypeParser::total, *a, rev);
1611 12 Feb 23 peter 146
803 10 Jul 09 peter 147         if (total!=total2) {
803 10 Jul 09 peter 148           suite.out() << "error: check_total\n"
803 10 Jul 09 peter 149                       << " author = " << *a << "\n"
803 10 Jul 09 peter 150                       << " rev = " << rev << "\n"
803 10 Jul 09 peter 151                       << " sum = " << total << "\n"
803 10 Jul 09 peter 152                       << " total = " << total2 << "\n";
803 10 Jul 09 peter 153           return false;
803 10 Jul 09 peter 154         }
803 10 Jul 09 peter 155       }
803 10 Jul 09 peter 156     }
803 10 Jul 09 peter 157     return true;
803 10 Jul 09 peter 158   }
803 10 Jul 09 peter 159
803 10 Jul 09 peter 160
803 10 Jul 09 peter 161   bool consistent(const StatsCollection& sc, test::Suite& suite)
803 10 Jul 09 peter 162   {
803 10 Jul 09 peter 163     std::map<std::string, Stats*>::const_iterator iter = sc.stats().begin();
803 10 Jul 09 peter 164     while (iter != sc.stats().end()) {
803 10 Jul 09 peter 165       if (!consistent(*iter->second, suite)) {
803 10 Jul 09 peter 166         suite.out() << "error in " << iter->first << "\n";
803 10 Jul 09 peter 167         return false;
803 10 Jul 09 peter 168       }
803 10 Jul 09 peter 169       ++iter;
803 10 Jul 09 peter 170     }
803 10 Jul 09 peter 171     return true;
803 10 Jul 09 peter 172   }
803 10 Jul 09 peter 173
803 10 Jul 09 peter 174
803 10 Jul 09 peter 175   bool consistent(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 176   {
803 10 Jul 09 peter 177     suite.add(check_all(stats, suite));
803 10 Jul 09 peter 178     suite.add(check_total(stats, suite));
803 10 Jul 09 peter 179     return true;
803 10 Jul 09 peter 180   }
803 10 Jul 09 peter 181
803 10 Jul 09 peter 182
1207 07 Oct 10 peter 183   bool diff(const std::string& a, const std::string& b)
1207 07 Oct 10 peter 184   {
1207 07 Oct 10 peter 185     if (a==b)
1207 07 Oct 10 peter 186       return false;
1207 07 Oct 10 peter 187
1207 07 Oct 10 peter 188     std::istringstream ssa(a);
1207 07 Oct 10 peter 189     std::istringstream ssb(b);
1207 07 Oct 10 peter 190
1207 07 Oct 10 peter 191     std::string linea;
1207 07 Oct 10 peter 192     std::string lineb;
1207 07 Oct 10 peter 193     while (ssa || ssb) {
1207 07 Oct 10 peter 194       if (!ssa) {
1207 07 Oct 10 peter 195         getline(ssb, lineb);
1207 07 Oct 10 peter 196         std::cout << "+ " << lineb << "\n";
1207 07 Oct 10 peter 197       }
1207 07 Oct 10 peter 198       else if (!ssb) {
1207 07 Oct 10 peter 199         getline(ssa, linea);
1207 07 Oct 10 peter 200         std::cout << "- " << lineb << "\n";
1207 07 Oct 10 peter 201       }
1207 07 Oct 10 peter 202       else {
1207 07 Oct 10 peter 203         getline(ssa, linea);
1207 07 Oct 10 peter 204         getline(ssb, lineb);
1207 07 Oct 10 peter 205         if (linea==lineb)
1207 07 Oct 10 peter 206           std::cout << "  " << linea << "\n";
1207 07 Oct 10 peter 207         else {
1207 07 Oct 10 peter 208           std::cout << "- " << linea << "\n";
1207 07 Oct 10 peter 209           std::cout << "+ " << lineb << "\n";
1207 07 Oct 10 peter 210         }
1207 07 Oct 10 peter 211       }
1207 07 Oct 10 peter 212     }
1207 07 Oct 10 peter 213     return true;
1207 07 Oct 10 peter 214   }
1207 07 Oct 10 peter 215
1207 07 Oct 10 peter 216
1611 12 Feb 23 peter 217   bool equal(const StatsCollection& a, const StatsCollection& b,
801 06 Jul 09 peter 218              Suite& suite)
801 06 Jul 09 peter 219   {
801 06 Jul 09 peter 220     if (a.stats().size() != b.stats().size()) {
801 06 Jul 09 peter 221       suite.out() << "size mismatch\n";
801 06 Jul 09 peter 222       return false;
801 06 Jul 09 peter 223     }
801 06 Jul 09 peter 224     std::map<std::string, Stats*>::const_iterator iter1 = a.stats().begin();
801 06 Jul 09 peter 225     std::map<std::string, Stats*>::const_iterator iter2 = b.stats().begin();
801 06 Jul 09 peter 226     while (iter1 != a.stats().end()) {
801 06 Jul 09 peter 227       if (iter1->first != iter2->first) {
801 06 Jul 09 peter 228         suite.out() << "key mismatch\n";
801 06 Jul 09 peter 229         suite.out() << iter1->first << " vs " << iter2->first << "\n";
801 06 Jul 09 peter 230         return false;
801 06 Jul 09 peter 231       }
801 06 Jul 09 peter 232       if (!equal(*iter1->second, *iter2->second, suite)) {
801 06 Jul 09 peter 233         suite.out() << "error in " << iter1->first << "\n";
801 06 Jul 09 peter 234         return false;
801 06 Jul 09 peter 235       }
801 06 Jul 09 peter 236       ++iter1;
801 06 Jul 09 peter 237       ++iter2;
801 06 Jul 09 peter 238     }
801 06 Jul 09 peter 239     return true;
801 06 Jul 09 peter 240   }
801 06 Jul 09 peter 241
1611 12 Feb 23 peter 242
801 06 Jul 09 peter 243   bool equal(const Stats& a, const Stats& b, test::Suite& suite)
801 06 Jul 09 peter 244   {
801 06 Jul 09 peter 245     if (a.authors() != b.authors()) {
801 06 Jul 09 peter 246       suite.out() << "authors are not equal\n";
803 10 Jul 09 peter 247       suite.out() << "lhs:\n";
803 10 Jul 09 peter 248       std::copy(a.authors().begin(), a.authors().end(), 
803 10 Jul 09 peter 249                 std::ostream_iterator<std::string>(suite.out(), "\n"));
803 10 Jul 09 peter 250       suite.out() << "rhs:\n";
1611 12 Feb 23 peter 251       std::copy(b.authors().begin(), b.authors().end(),
803 10 Jul 09 peter 252                 std::ostream_iterator<std::string>(suite.out(), "\n"));
801 06 Jul 09 peter 253       return false;
801 06 Jul 09 peter 254     }
801 06 Jul 09 peter 255     if (a.revision() != b.revision()) {
801 06 Jul 09 peter 256       suite.out() << "revision mismatch\n";
801 06 Jul 09 peter 257       return false;
801 06 Jul 09 peter 258     }
801 06 Jul 09 peter 259     std::vector<std::string> authors;
801 06 Jul 09 peter 260     authors.reserve(a.authors().size()+1);
1611 12 Feb 23 peter 261     std::copy(a.authors().begin(), a.authors().end(),
801 06 Jul 09 peter 262               std::back_inserter(authors));
801 06 Jul 09 peter 263     authors.push_back("all");
1611 12 Feb 23 peter 264     for (int linetype : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 265                          LineTypeParser::other, LineTypeParser::total}) {
1611 12 Feb 23 peter 266       for (std::vector<std::string>::const_iterator author=authors.begin();
801 06 Jul 09 peter 267            author!=authors.end(); ++author) {
801 06 Jul 09 peter 268         for (svn_revnum_t rev=0; rev<a.revision(); ++rev) {
801 06 Jul 09 peter 269           size_t ax = a(linetype, *author, rev);
801 06 Jul 09 peter 270           size_t bx = b(linetype, *author, rev);
801 06 Jul 09 peter 271           if (ax != bx) {
1611 12 Feb 23 peter 272             suite.out() << "error: linetype: " << linetype
1611 12 Feb 23 peter 273                         << " author " << *author
801 06 Jul 09 peter 274                         << " rev " << rev << "\n"
801 06 Jul 09 peter 275                         << "   a: " << ax << "\n"
801 06 Jul 09 peter 276                         << "   b: " << bx << "\n";
801 06 Jul 09 peter 277             return false;
801 06 Jul 09 peter 278           }
801 06 Jul 09 peter 279         }
801 06 Jul 09 peter 280       }
801 06 Jul 09 peter 281     }
801 06 Jul 09 peter 282     return true;
801 06 Jul 09 peter 283   }
801 06 Jul 09 peter 284
801 06 Jul 09 peter 285
744 08 Jan 09 peter 286   void Suite::update_test_wc(void) const
744 08 Jan 09 peter 287   {
744 08 Jan 09 peter 288     std::string cmd = abs_builddir()+"/svn_update.sh";
1478 29 May 12 peter 289     try {
1478 29 May 12 peter 290       system(cmd, 0);
1478 29 May 12 peter 291     }
1478 29 May 12 peter 292     catch (std::runtime_error& e) {
1478 29 May 12 peter 293       out() << e.what() << "\n";
744 08 Jan 09 peter 294       exit (1);
744 08 Jan 09 peter 295     }
744 08 Jan 09 peter 296   }
744 08 Jan 09 peter 297
744 08 Jan 09 peter 298
744 08 Jan 09 peter 299   bool Suite::verbose(void) const
744 08 Jan 09 peter 300   {
1044 27 Mar 10 peter 301     // we are always verbose nowadays
1044 27 Mar 10 peter 302     return true;
744 08 Jan 09 peter 303   }
744 08 Jan 09 peter 304
744 08 Jan 09 peter 305
596 14 Apr 08 peter 306   std::string filename(const std::string& path)
596 14 Apr 08 peter 307   {
737 15 Dec 08 peter 308     return abs_builddir()+"/"+path;
596 14 Apr 08 peter 309   }
596 14 Apr 08 peter 310
596 14 Apr 08 peter 311
801 06 Jul 09 peter 312   std::string src_filename(const std::string& path)
801 06 Jul 09 peter 313   {
801 06 Jul 09 peter 314     return abs_srcdir()+"/"+path;
801 06 Jul 09 peter 315   }
801 06 Jul 09 peter 316
801 06 Jul 09 peter 317
1478 29 May 12 peter 318   void Suite::system(const std::string& cmd, int ret) const
1478 29 May 12 peter 319   {
1478 29 May 12 peter 320     int status = ::system(cmd.c_str());
1478 29 May 12 peter 321     out() << "call: '" << cmd << "'\n";
1478 29 May 12 peter 322     if (status==ret)
1478 29 May 12 peter 323       return;
1478 29 May 12 peter 324     std::stringstream ss;
1478 29 May 12 peter 325     ss << "error: status: " << status;
1478 29 May 12 peter 326     throw std::runtime_error(ss.str());
1478 29 May 12 peter 327   }
596 14 Apr 08 peter 328 }}}