source: trunk/test/Suite.cc @ 1092

Last change on this file since 1092 was 1092, checked in by Peter Johansson, 13 years ago

fixes #445. tests are now performed in testSubDir/foo and each test has its own wc (and own svndigest cache) to work on.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1// $Id: Suite.cc 1092 2010-06-12 23:50:18Z peter $
2
3/*
4  Copyright (C) 2008 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2009, 2010 Peter Johansson
6
7  This file is part of the yat library, http://dev.thep.lu.se/yat
8
9  The yat library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 3 of the
12  License, or (at your option) any later version.
13
14  The yat library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include <config.h>
24
25#include "Suite.h"
26#include "environment.h"
27
28#include "Stats.h"
29#include "StatsCollection.h"
30#include "../lib/utility.h"
31
32#include <algorithm>
33#include <cassert>
34#include <fstream>
35#include <iostream>
36#include <iterator>
37#include <string>
38
39namespace theplu {
40namespace svndigest {
41namespace test {
42
43  Suite::Suite(int argc, char* argv[], bool need_test_repo)
44    : ok_(true)
45  {
46    chdir(abs_builddir());
47    std::string test_dir = concatenate_path("testSubDir", file_name(argv[0]));
48    mkdir_p(test_dir);
49    chdir(test_dir);
50    if (need_test_repo) {
51      bool have_test_repo=false;
52      #ifdef HAVE_TEST_REPO
53      have_test_repo=true;
54      #endif
55      if (!have_test_repo) {
56        out() << "Skipping test because test repository is not available\n";
57        exit (77);
58      }
59      update_test_wc();
60    }
61
62  }
63
64
65  Suite::~Suite(void)
66  {
67  }
68
69 
70  bool Suite::add(bool b)
71  {
72    ok_ = ok_ && b;
73    return b;
74  }
75
76
77  bool Suite::ok(void) const
78  {
79    return ok_;
80  }
81
82
83  std::ostream& Suite::out(void) const
84  {
85    return std::cout;
86  }
87
88
89  bool check_all(const Stats& stats, test::Suite& suite)
90  {
91    for (int lt=0; lt<=LineTypeParser::total; ++lt) {
92      for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
93        size_t all = 0;
94        for (std::set<std::string>::const_iterator a=stats.authors().begin();
95             a!=stats.authors().end(); ++a) {
96          all += stats(lt, *a, rev);
97        }
98        if (all!=stats(lt, "all", rev)) {
99          suite.out() << "error: check_all\n"
100                      << " lt = " << lt << "\n"
101                      << " rev = " << rev << "\n"
102                      << " all = " << all << "\n"
103                      << " stats = " << stats(lt, "all", rev) << "\n";
104          for (std::set<std::string>::const_iterator a=stats.authors().begin();
105               a!=stats.authors().end(); ++a) {
106            suite.out() << *a << " " << stats(lt, *a, rev) << "\n";
107          }
108          return false;
109        }
110      }
111    }
112    return true;
113  }
114 
115
116  bool check_total(const Stats& stats, test::Suite& suite)
117  {
118    for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
119      for (std::set<std::string>::const_iterator a=stats.authors().begin();
120           a!=stats.authors().end(); ++a) {
121        unsigned int total=0;
122        for (int lt=0; lt<4; ++lt) {
123          total += stats(lt, *a, rev);
124        }
125        unsigned int total2=stats(LineTypeParser::total, *a, rev);
126       
127        if (total!=total2) {
128          suite.out() << "error: check_total\n"
129                      << " author = " << *a << "\n"
130                      << " rev = " << rev << "\n"
131                      << " sum = " << total << "\n"
132                      << " total = " << total2 << "\n";
133          return false;
134        }
135      }
136    }
137    return true;
138  }
139 
140
141  bool check_comment_or_copy(const Stats& stats, test::Suite& suite)
142  {
143    for (svn_revnum_t rev=0; rev<=stats.revision(); ++rev) {
144      for (std::set<std::string>::const_iterator a=stats.authors().begin();
145           a!=stats.authors().end(); ++a) {
146        unsigned int x=stats(LineTypeParser::comment, *a, rev);
147        x+=stats(LineTypeParser::copyright, *a, rev);
148        unsigned int y=stats(LineTypeParser::comment_or_copy, *a, rev);
149       
150        if (x!=y) {
151          suite.out() << "error: check_total\n"
152                      << " author = " << *a << "\n"
153                      << " rev = " << rev << "\n"
154                      << " comment + copyright = " << x << "\n"
155                      << " comment_or_copy = " << y << "\n";
156          return false;
157        }
158      }
159    }
160    return true;
161  }
162
163
164  bool consistent(const StatsCollection& sc, test::Suite& suite)
165  {
166    std::map<std::string, Stats*>::const_iterator iter = sc.stats().begin();
167    while (iter != sc.stats().end()) {
168      if (!consistent(*iter->second, suite)) {
169        suite.out() << "error in " << iter->first << "\n";
170        return false;
171      }
172      ++iter;
173    }
174    return true;
175  }
176
177
178  bool consistent(const Stats& stats, test::Suite& suite)
179  {
180    suite.add(check_all(stats, suite));
181    suite.add(check_total(stats, suite));
182    suite.add(check_comment_or_copy(stats, suite));
183    return true;
184  }
185
186
187  bool equal(const StatsCollection& a, const StatsCollection& b, 
188             Suite& suite)
189  {
190    if (a.stats().size() != b.stats().size()) {
191      suite.out() << "size mismatch\n";
192      return false;
193    }
194    std::map<std::string, Stats*>::const_iterator iter1 = a.stats().begin();
195    std::map<std::string, Stats*>::const_iterator iter2 = b.stats().begin();
196    while (iter1 != a.stats().end()) {
197      if (iter1->first != iter2->first) {
198        suite.out() << "key mismatch\n";
199        suite.out() << iter1->first << " vs " << iter2->first << "\n";
200        return false;
201      }
202      if (!equal(*iter1->second, *iter2->second, suite)) {
203        suite.out() << "error in " << iter1->first << "\n";
204        return false;
205      }
206      ++iter1;
207      ++iter2;
208    }
209    return true;
210  }
211 
212
213  bool equal(const Stats& a, const Stats& b, test::Suite& suite)
214  {
215    if (a.authors() != b.authors()) {
216      suite.out() << "authors are not equal\n";
217      suite.out() << "lhs:\n";
218      std::copy(a.authors().begin(), a.authors().end(), 
219                std::ostream_iterator<std::string>(suite.out(), "\n"));
220      suite.out() << "rhs:\n";
221      std::copy(b.authors().begin(), b.authors().end(), 
222                std::ostream_iterator<std::string>(suite.out(), "\n"));
223      return false;
224    }
225    if (a.revision() != b.revision()) {
226      suite.out() << "revision mismatch\n";
227      return false;
228    }
229    std::vector<std::string> authors;
230    authors.reserve(a.authors().size()+1);
231    std::copy(a.authors().begin(), a.authors().end(), 
232              std::back_inserter(authors));
233    authors.push_back("all");
234    for (int linetype=0; linetype <= LineTypeParser::total; ++linetype) {
235      for (std::vector<std::string>::const_iterator author=authors.begin(); 
236           author!=authors.end(); ++author) {
237        for (svn_revnum_t rev=0; rev<a.revision(); ++rev) {
238          size_t ax = a(linetype, *author, rev);
239          size_t bx = b(linetype, *author, rev);
240          if (ax != bx) {
241            suite.out() << "error: linetype: " << linetype
242                        << " author " << *author 
243                        << " rev " << rev << "\n"
244                        << "   a: " << ax << "\n"
245                        << "   b: " << bx << "\n";
246            return false;
247          }
248        }
249      }
250    }
251    return true;
252  }
253
254
255  void Suite::update_test_wc(void) const
256  {
257    std::string cmd = abs_builddir()+"/svn_update.sh";
258    out() << cmd << std::endl;
259    int status = system(cmd.c_str());
260    if (status) {
261      out() << "failed with status: " << status << std::endl;
262      exit (1);
263    }
264  }
265
266
267  bool Suite::verbose(void) const
268  {
269    // we are always verbose nowadays
270    return true;
271  }
272
273
274  std::string filename(const std::string& path)
275  {
276    return abs_builddir()+"/"+path;
277  }
278
279
280  std::string src_filename(const std::string& path)
281  {
282    return abs_srcdir()+"/"+path;
283  }
284
285
286}}}
Note: See TracBrowser for help on using the repository browser.