1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <string>
20 #include <cppunit/TestRunner.h>
21 #include <cppunit/CompilerOutputter.h>
22 #include <cppunit/TestResult.h>
23 #include <cppunit/TestResultCollector.h>
24 #include <cppunit/TextTestProgressListener.h>
25 #include <cppunit/BriefTestProgressListener.h>
26 #include <cppunit/extensions/TestFactoryRegistry.h>
27 #include <signal.h>
28 #include <stdlib.h>
29 #include <stdexcept>
30 #include <unistd.h>
31 #include <sys/select.h>
32 #include <cppunit/Exception.h>
33 #include <cppunit/TestFailure.h>
34 #include <cppunit/XmlOutputter.h>
35 #include <cppunit/TestAssert.h>
36 #include <fstream>
37 #include <time.h>
38 
39 #include "Util.h"
40 #include "zookeeper_log.h"
41 
42 using namespace std;
43 
44 CPPUNIT_NS_BEGIN
45 
46 class EclipseOutputter: public CompilerOutputter
47 {
48 public:
EclipseOutputter(TestResultCollector * result,ostream & stream)49   EclipseOutputter(TestResultCollector *result,ostream &stream):
50         CompilerOutputter(result,stream,"%p:%l: "),stream_(stream)
51     {
52     }
printFailedTestName(TestFailure * failure)53     virtual void printFailedTestName( TestFailure *failure ){}
printFailureMessage(TestFailure * failure)54     virtual void printFailureMessage( TestFailure *failure )
55     {
56       stream_<<": ";
57       Message msg = failure->thrownException()->message();
58       stream_<< msg.shortDescription();
59 
60       string text;
61       for(int i=0; i<msg.detailCount();i++){
62           text+=msg.detailAt(i);
63           if(i+1!=msg.detailCount())
64               text+=", ";
65       }
66       if(text.length()!=0)
67           stream_ <<" ["<<text<<"]";
68       stream_<<"\n";
69     }
70     ostream& stream_;
71 };
72 
73 CPPUNIT_NS_END
74 
75 class TimingListener : public CPPUNIT_NS::BriefTestProgressListener {
76  public:
startTest(CPPUNIT_NS::Test * test)77    void startTest( CPPUNIT_NS::Test *test )
78    {
79      gettimeofday(&_start_time, NULL);
80 
81      CPPUNIT_NS::BriefTestProgressListener::startTest(test);
82    }
83 
endTest(CPPUNIT_NS::Test * test)84    void endTest( CPPUNIT_NS::Test *test )
85    {
86      struct timeval end;
87      gettimeofday(&end, NULL);
88 
89      long seconds = end.tv_sec - _start_time.tv_sec;
90      long useconds = end.tv_usec - _start_time.tv_usec;
91 
92      long mtime = seconds * 1000 + useconds/1000.0;
93      CPPUNIT_NS::stdCOut()  <<  " : elapsed " <<  mtime;
94      CPPUNIT_NS::BriefTestProgressListener::endTest(test);
95    }
96 
97  private:
98    struct timeval _start_time;
99 };
100 
101 class ZKServer {
102 public:
ZKServer()103     ZKServer() {
104         char cmd[1024];
105         sprintf(cmd, "%s startClean %s", ZKSERVER_CMD, "127.0.0.1:22181");
106         CPPUNIT_ASSERT(system(cmd) == 0);
107 
108         struct sigaction act;
109         act.sa_handler = SIG_IGN;
110         sigemptyset(&act.sa_mask);
111         act.sa_flags = 0;
112         CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
113     }
~ZKServer()114     virtual ~ZKServer(){
115         char cmd[1024];
116         sprintf(cmd, "%s stop %s", ZKSERVER_CMD, "127.0.0.1:22181");
117         CPPUNIT_ASSERT(system(cmd) == 0);
118     }
119 };
120 
main(int argc,char * argv[])121 int main( int argc, char* argv[] ) {
122    // if command line contains "-ide" then this is the post build check
123    // => the output must be in the compiler error format.
124    //bool selfTest = (argc > 1) && (std::string("-ide") == argv[1]);
125    globalTestConfig.addConfigFromCmdLine(argc,argv);
126 
127    ZKServer zkserver;
128 
129    // Create the event manager and test controller
130    CPPUNIT_NS::TestResult controller;
131    // Add a listener that colllects test result
132    CPPUNIT_NS::TestResultCollector result;
133    controller.addListener( &result );
134 
135    // A listener that print dots as tests run.
136    // CPPUNIT_NS::TextTestProgressListener progress;
137    // CPPUNIT_NS::BriefTestProgressListener progress;
138 
139    // brief + elapsed time
140    TimingListener progress;
141    controller.addListener( &progress );
142 
143    CPPUNIT_NS::TestRunner runner;
144    runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
145 
146    try {
147      CPPUNIT_NS::stdCOut() << endl << "Running " << endl;
148 
149      zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
150      //zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
151 
152      runner.run( controller, globalTestConfig.getTestName());
153 
154      // Print test in a compiler compatible format.
155      CPPUNIT_NS::EclipseOutputter outputter( &result,cout);
156      outputter.write();
157 
158  // Uncomment this for XML output
159 #ifdef ENABLE_XML_OUTPUT
160      std::ofstream file( "tests.xml" );
161      CPPUNIT_NS::XmlOutputter xml( &result, file );
162      xml.setStyleSheet( "report.xsl" );
163      xml.write();
164      file.close();
165 #endif
166    } catch ( std::invalid_argument &e ) {
167      // Test path not resolved
168      cout<<"\nERROR: "<<e.what()<<endl;
169      return 0;
170    }
171 
172    return result.wasSuccessful() ? 0 : 1;
173  }
174