source: trunk/test/Suite.cc @ 809

Last change on this file since 809 was 803, checked in by Peter Johansson, 12 years ago

fixes #338 - partial cache now works

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