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
803 10 Jul 09 peter 33 #include <algorithm>
1478 29 May 12 peter 34 #include <cstdlib>
744 08 Jan 09 peter 35 #include <fstream>
744 08 Jan 09 peter 36 #include <iostream>
803 10 Jul 09 peter 37 #include <iterator>
1478 29 May 12 peter 38 #include <sstream>
1478 29 May 12 peter 39 #include <stdexcept>
596 14 Apr 08 peter 40 #include <string>
596 14 Apr 08 peter 41
596 14 Apr 08 peter 42 namespace theplu {
596 14 Apr 08 peter 43 namespace svndigest {
596 14 Apr 08 peter 44 namespace test {
596 14 Apr 08 peter 45
744 08 Jan 09 peter 46   Suite::Suite(int argc, char* argv[], bool need_test_repo)
1044 27 Mar 10 peter 47     : ok_(true)
744 08 Jan 09 peter 48   {
1092 12 Jun 10 peter 49     chdir(abs_builddir());
1092 12 Jun 10 peter 50     std::string test_dir = concatenate_path("testSubDir", file_name(argv[0]));
1092 12 Jun 10 peter 51     mkdir_p(test_dir);
1092 12 Jun 10 peter 52     chdir(test_dir);
1104 15 Jun 10 peter 53     out() << "running `" << argv[0] << "' in `" << test_dir << "'\n";
744 08 Jan 09 peter 54     if (need_test_repo) {
744 08 Jan 09 peter 55       bool have_test_repo=false;
744 08 Jan 09 peter 56       #ifdef HAVE_TEST_REPO
744 08 Jan 09 peter 57       have_test_repo=true;
744 08 Jan 09 peter 58       #endif
744 08 Jan 09 peter 59       if (!have_test_repo) {
744 08 Jan 09 peter 60         out() << "Skipping test because test repository is not available\n";
1182 25 Aug 10 peter 61         exit (EXIT_SKIP);
744 08 Jan 09 peter 62       }
744 08 Jan 09 peter 63       update_test_wc();
744 08 Jan 09 peter 64     }
744 08 Jan 09 peter 65
744 08 Jan 09 peter 66   }
744 08 Jan 09 peter 67
744 08 Jan 09 peter 68
744 08 Jan 09 peter 69   Suite::~Suite(void)
744 08 Jan 09 peter 70   {
744 08 Jan 09 peter 71   }
744 08 Jan 09 peter 72
1611 12 Feb 23 peter 73
744 08 Jan 09 peter 74   bool Suite::add(bool b)
744 08 Jan 09 peter 75   {
744 08 Jan 09 peter 76     ok_ = ok_ && b;
744 08 Jan 09 peter 77     return b;
744 08 Jan 09 peter 78   }
744 08 Jan 09 peter 79
744 08 Jan 09 peter 80
1162 13 Aug 10 peter 81   int Suite::exit_status(void) const
1162 13 Aug 10 peter 82   {
1162 13 Aug 10 peter 83     int value = EXIT_FAILURE;
1162 13 Aug 10 peter 84     if (ok()) {
1611 12 Feb 23 peter 85       value = EXIT_SUCCESS;
1162 13 Aug 10 peter 86     }
1162 13 Aug 10 peter 87     out() << "exit status: " << value << "\n";
1162 13 Aug 10 peter 88     return value;
1162 13 Aug 10 peter 89   }
1162 13 Aug 10 peter 90
1162 13 Aug 10 peter 91
744 08 Jan 09 peter 92   bool Suite::ok(void) const
744 08 Jan 09 peter 93   {
744 08 Jan 09 peter 94     return ok_;
744 08 Jan 09 peter 95   }
744 08 Jan 09 peter 96
744 08 Jan 09 peter 97
744 08 Jan 09 peter 98   std::ostream& Suite::out(void) const
744 08 Jan 09 peter 99   {
1044 27 Mar 10 peter 100     return std::cout;
744 08 Jan 09 peter 101   }
744 08 Jan 09 peter 102
744 08 Jan 09 peter 103
803 10 Jul 09 peter 104   bool check_all(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 105   {
1611 12 Feb 23 peter 106     for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 107                    LineTypeParser::other, LineTypeParser::total}) {
803 10 Jul 09 peter 108       for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
803 10 Jul 09 peter 109         size_t all = 0;
803 10 Jul 09 peter 110         for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 111              a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 112           all += stats(lt, *a, rev);
803 10 Jul 09 peter 113         }
803 10 Jul 09 peter 114         if (all!=stats(lt, "all", rev)) {
803 10 Jul 09 peter 115           suite.out() << "error: check_all\n"
803 10 Jul 09 peter 116                       << " lt = " << lt << "\n"
803 10 Jul 09 peter 117                       << " rev = " << rev << "\n"
803 10 Jul 09 peter 118                       << " all = " << all << "\n"
803 10 Jul 09 peter 119                       << " stats = " << stats(lt, "all", rev) << "\n";
803 10 Jul 09 peter 120           for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 121                a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 122             suite.out() << *a << " " << stats(lt, *a, rev) << "\n";
803 10 Jul 09 peter 123           }
803 10 Jul 09 peter 124           return false;
803 10 Jul 09 peter 125         }
803 10 Jul 09 peter 126       }
803 10 Jul 09 peter 127     }
803 10 Jul 09 peter 128     return true;
803 10 Jul 09 peter 129   }
803 10 Jul 09 peter 130
1611 12 Feb 23 peter 131
803 10 Jul 09 peter 132   bool check_total(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 133   {
803 10 Jul 09 peter 134     for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
803 10 Jul 09 peter 135       for (std::set<std::string>::const_iterator a=stats.authors().begin();
803 10 Jul 09 peter 136            a!=stats.authors().end(); ++a) {
803 10 Jul 09 peter 137         unsigned int total=0;
1611 12 Feb 23 peter 138         for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 139                        LineTypeParser::other}) {
803 10 Jul 09 peter 140           total += stats(lt, *a, rev);
803 10 Jul 09 peter 141         }
803 10 Jul 09 peter 142         unsigned int total2=stats(LineTypeParser::total, *a, rev);
1611 12 Feb 23 peter 143
803 10 Jul 09 peter 144         if (total!=total2) {
803 10 Jul 09 peter 145           suite.out() << "error: check_total\n"
803 10 Jul 09 peter 146                       << " author = " << *a << "\n"
803 10 Jul 09 peter 147                       << " rev = " << rev << "\n"
803 10 Jul 09 peter 148                       << " sum = " << total << "\n"
803 10 Jul 09 peter 149                       << " total = " << total2 << "\n";
803 10 Jul 09 peter 150           return false;
803 10 Jul 09 peter 151         }
803 10 Jul 09 peter 152       }
803 10 Jul 09 peter 153     }
803 10 Jul 09 peter 154     return true;
803 10 Jul 09 peter 155   }
803 10 Jul 09 peter 156
803 10 Jul 09 peter 157
803 10 Jul 09 peter 158   bool consistent(const StatsCollection& sc, test::Suite& suite)
803 10 Jul 09 peter 159   {
803 10 Jul 09 peter 160     std::map<std::string, Stats*>::const_iterator iter = sc.stats().begin();
803 10 Jul 09 peter 161     while (iter != sc.stats().end()) {
803 10 Jul 09 peter 162       if (!consistent(*iter->second, suite)) {
803 10 Jul 09 peter 163         suite.out() << "error in " << iter->first << "\n";
803 10 Jul 09 peter 164         return false;
803 10 Jul 09 peter 165       }
803 10 Jul 09 peter 166       ++iter;
803 10 Jul 09 peter 167     }
803 10 Jul 09 peter 168     return true;
803 10 Jul 09 peter 169   }
803 10 Jul 09 peter 170
803 10 Jul 09 peter 171
803 10 Jul 09 peter 172   bool consistent(const Stats& stats, test::Suite& suite)
803 10 Jul 09 peter 173   {
803 10 Jul 09 peter 174     suite.add(check_all(stats, suite));
803 10 Jul 09 peter 175     suite.add(check_total(stats, suite));
803 10 Jul 09 peter 176     return true;
803 10 Jul 09 peter 177   }
803 10 Jul 09 peter 178
803 10 Jul 09 peter 179
1207 07 Oct 10 peter 180   bool diff(const std::string& a, const std::string& b)
1207 07 Oct 10 peter 181   {
1207 07 Oct 10 peter 182     if (a==b)
1207 07 Oct 10 peter 183       return false;
1207 07 Oct 10 peter 184
1207 07 Oct 10 peter 185     std::istringstream ssa(a);
1207 07 Oct 10 peter 186     std::istringstream ssb(b);
1207 07 Oct 10 peter 187
1207 07 Oct 10 peter 188     std::string linea;
1207 07 Oct 10 peter 189     std::string lineb;
1207 07 Oct 10 peter 190     while (ssa || ssb) {
1207 07 Oct 10 peter 191       if (!ssa) {
1207 07 Oct 10 peter 192         getline(ssb, lineb);
1207 07 Oct 10 peter 193         std::cout << "+ " << lineb << "\n";
1207 07 Oct 10 peter 194       }
1207 07 Oct 10 peter 195       else if (!ssb) {
1207 07 Oct 10 peter 196         getline(ssa, linea);
1207 07 Oct 10 peter 197         std::cout << "- " << lineb << "\n";
1207 07 Oct 10 peter 198       }
1207 07 Oct 10 peter 199       else {
1207 07 Oct 10 peter 200         getline(ssa, linea);
1207 07 Oct 10 peter 201         getline(ssb, lineb);
1207 07 Oct 10 peter 202         if (linea==lineb)
1207 07 Oct 10 peter 203           std::cout << "  " << linea << "\n";
1207 07 Oct 10 peter 204         else {
1207 07 Oct 10 peter 205           std::cout << "- " << linea << "\n";
1207 07 Oct 10 peter 206           std::cout << "+ " << lineb << "\n";
1207 07 Oct 10 peter 207         }
1207 07 Oct 10 peter 208       }
1207 07 Oct 10 peter 209     }
1207 07 Oct 10 peter 210     return true;
1207 07 Oct 10 peter 211   }
1207 07 Oct 10 peter 212
1207 07 Oct 10 peter 213
1611 12 Feb 23 peter 214   bool equal(const StatsCollection& a, const StatsCollection& b,
801 06 Jul 09 peter 215              Suite& suite)
801 06 Jul 09 peter 216   {
801 06 Jul 09 peter 217     if (a.stats().size() != b.stats().size()) {
801 06 Jul 09 peter 218       suite.out() << "size mismatch\n";
801 06 Jul 09 peter 219       return false;
801 06 Jul 09 peter 220     }
801 06 Jul 09 peter 221     std::map<std::string, Stats*>::const_iterator iter1 = a.stats().begin();
801 06 Jul 09 peter 222     std::map<std::string, Stats*>::const_iterator iter2 = b.stats().begin();
801 06 Jul 09 peter 223     while (iter1 != a.stats().end()) {
801 06 Jul 09 peter 224       if (iter1->first != iter2->first) {
801 06 Jul 09 peter 225         suite.out() << "key mismatch\n";
801 06 Jul 09 peter 226         suite.out() << iter1->first << " vs " << iter2->first << "\n";
801 06 Jul 09 peter 227         return false;
801 06 Jul 09 peter 228       }
801 06 Jul 09 peter 229       if (!equal(*iter1->second, *iter2->second, suite)) {
801 06 Jul 09 peter 230         suite.out() << "error in " << iter1->first << "\n";
801 06 Jul 09 peter 231         return false;
801 06 Jul 09 peter 232       }
801 06 Jul 09 peter 233       ++iter1;
801 06 Jul 09 peter 234       ++iter2;
801 06 Jul 09 peter 235     }
801 06 Jul 09 peter 236     return true;
801 06 Jul 09 peter 237   }
801 06 Jul 09 peter 238
1611 12 Feb 23 peter 239
801 06 Jul 09 peter 240   bool equal(const Stats& a, const Stats& b, test::Suite& suite)
801 06 Jul 09 peter 241   {
801 06 Jul 09 peter 242     if (a.authors() != b.authors()) {
801 06 Jul 09 peter 243       suite.out() << "authors are not equal\n";
803 10 Jul 09 peter 244       suite.out() << "lhs:\n";
803 10 Jul 09 peter 245       std::copy(a.authors().begin(), a.authors().end(), 
803 10 Jul 09 peter 246                 std::ostream_iterator<std::string>(suite.out(), "\n"));
803 10 Jul 09 peter 247       suite.out() << "rhs:\n";
1611 12 Feb 23 peter 248       std::copy(b.authors().begin(), b.authors().end(),
803 10 Jul 09 peter 249                 std::ostream_iterator<std::string>(suite.out(), "\n"));
801 06 Jul 09 peter 250       return false;
801 06 Jul 09 peter 251     }
801 06 Jul 09 peter 252     if (a.revision() != b.revision()) {
801 06 Jul 09 peter 253       suite.out() << "revision mismatch\n";
801 06 Jul 09 peter 254       return false;
801 06 Jul 09 peter 255     }
801 06 Jul 09 peter 256     std::vector<std::string> authors;
801 06 Jul 09 peter 257     authors.reserve(a.authors().size()+1);
1611 12 Feb 23 peter 258     std::copy(a.authors().begin(), a.authors().end(),
801 06 Jul 09 peter 259               std::back_inserter(authors));
801 06 Jul 09 peter 260     authors.push_back("all");
1611 12 Feb 23 peter 261     for (int linetype : {LineTypeParser::code, LineTypeParser::comment_or_copy,
1611 12 Feb 23 peter 262                          LineTypeParser::other, LineTypeParser::total}) {
1611 12 Feb 23 peter 263       for (std::vector<std::string>::const_iterator author=authors.begin();
801 06 Jul 09 peter 264            author!=authors.end(); ++author) {
801 06 Jul 09 peter 265         for (svn_revnum_t rev=0; rev<a.revision(); ++rev) {
801 06 Jul 09 peter 266           size_t ax = a(linetype, *author, rev);
801 06 Jul 09 peter 267           size_t bx = b(linetype, *author, rev);
801 06 Jul 09 peter 268           if (ax != bx) {
1611 12 Feb 23 peter 269             suite.out() << "error: linetype: " << linetype
1611 12 Feb 23 peter 270                         << " author " << *author
801 06 Jul 09 peter 271                         << " rev " << rev << "\n"
801 06 Jul 09 peter 272                         << "   a: " << ax << "\n"
801 06 Jul 09 peter 273                         << "   b: " << bx << "\n";
801 06 Jul 09 peter 274             return false;
801 06 Jul 09 peter 275           }
801 06 Jul 09 peter 276         }
801 06 Jul 09 peter 277       }
801 06 Jul 09 peter 278     }
801 06 Jul 09 peter 279     return true;
801 06 Jul 09 peter 280   }
801 06 Jul 09 peter 281
801 06 Jul 09 peter 282
744 08 Jan 09 peter 283   void Suite::update_test_wc(void) const
744 08 Jan 09 peter 284   {
744 08 Jan 09 peter 285     std::string cmd = abs_builddir()+"/svn_update.sh";
1478 29 May 12 peter 286     try {
1478 29 May 12 peter 287       system(cmd, 0);
1478 29 May 12 peter 288     }
1478 29 May 12 peter 289     catch (std::runtime_error& e) {
1478 29 May 12 peter 290       out() << e.what() << "\n";
744 08 Jan 09 peter 291       exit (1);
744 08 Jan 09 peter 292     }
744 08 Jan 09 peter 293   }
744 08 Jan 09 peter 294
744 08 Jan 09 peter 295
744 08 Jan 09 peter 296   bool Suite::verbose(void) const
744 08 Jan 09 peter 297   {
1044 27 Mar 10 peter 298     // we are always verbose nowadays
1044 27 Mar 10 peter 299     return true;
744 08 Jan 09 peter 300   }
744 08 Jan 09 peter 301
744 08 Jan 09 peter 302
596 14 Apr 08 peter 303   std::string filename(const std::string& path)
596 14 Apr 08 peter 304   {
737 15 Dec 08 peter 305     return abs_builddir()+"/"+path;
596 14 Apr 08 peter 306   }
596 14 Apr 08 peter 307
596 14 Apr 08 peter 308
801 06 Jul 09 peter 309   std::string src_filename(const std::string& path)
801 06 Jul 09 peter 310   {
801 06 Jul 09 peter 311     return abs_srcdir()+"/"+path;
801 06 Jul 09 peter 312   }
801 06 Jul 09 peter 313
801 06 Jul 09 peter 314
1478 29 May 12 peter 315   void Suite::system(const std::string& cmd, int ret) const
1478 29 May 12 peter 316   {
1478 29 May 12 peter 317     int status = ::system(cmd.c_str());
1478 29 May 12 peter 318     out() << "call: '" << cmd << "'\n";
1478 29 May 12 peter 319     if (status==ret)
1478 29 May 12 peter 320       return;
1478 29 May 12 peter 321     std::stringstream ss;
1478 29 May 12 peter 322     ss << "error: status: " << status;
1478 29 May 12 peter 323     throw std::runtime_error(ss.str());
1478 29 May 12 peter 324   }
596 14 Apr 08 peter 325 }}}