ProteoWizard
IterationListenerTest.cpp
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Darren Kessner <darren@proteowizard.org>
6//
7// Copyright 2008 Spielberg Family Center for Applied Proteomics
8// Cedars Sinai Medical Center, Los Angeles, California 90048
9//
10// Licensed under the Apache License, Version 2.0 (the "License");
11// you may not use this file except in compliance with the License.
12// You may obtain a copy of the License at
13//
14// http://www.apache.org/licenses/LICENSE-2.0
15//
16// Unless required by applicable law or agreed to in writing, software
17// distributed under the License is distributed on an "AS IS" BASIS,
18// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// See the License for the specific language governing permissions and
20// limitations under the License.
21//
22
23
24#include "Std.hpp"
25#include "IterationListener.hpp"
27#include <cstring>
28#include <ctime>
29
30
31using namespace pwiz::util;
32
33
34ostream* os_ = 0;
35
36
38{
39 public:
40
41 TestListener(const string& name)
42 : name_(name), count_(0)
43 {}
44
45 virtual Status update(const UpdateMessage& updateMessage)
46 {
47 if (os_) *os_ << "[" << name_ << "] " << updateMessage.iterationIndex << "/"
48 << updateMessage.iterationCount << endl;
49 count_++;
50 return Status_Ok;
51 }
52
53 size_t count() const {return count_;}
54
55 private:
56 string name_;
57 size_t count_;
58};
59
60
62{
63 public:
64
65 CancelListener(size_t cancelIndex)
66 : cancelIndex_(cancelIndex)
67 {}
68
69 virtual Status update(const UpdateMessage& updateMessage)
70 {
71 if (os_) *os_ << "[cancel] " << updateMessage.iterationIndex << "/"
72 << updateMessage.iterationCount << endl;
73
74 return updateMessage.iterationIndex==cancelIndex_ ? Status_Cancel : Status_Ok;
75 }
76
77 private:
79};
80
81
82// null deallactor to create shared_ptrs that do not delete when reset
84{
85 // do nothing
86}
87
88void test()
89{
90 if (os_) *os_ << "test()\n";
91
93
94 TestListener test3("test3");
95 TestListener test4("test4");
96 TestListener test5("test5");
97 TestListener test6("test6");
98
101 registry.addListener(IterationListenerPtr(&test5, nullDeallocate), 5);
102 registry.addListener(IterationListenerPtr(&test6, nullDeallocate), 6);
103
104 size_t iterationCount = 24;
105 for (size_t i=0; i<iterationCount; i++)
106 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(i, iterationCount));
107
108 // repeating last iteration should not create new messages
109 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(iterationCount - 1, iterationCount));
110 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(iterationCount - 1, iterationCount));
111 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(iterationCount - 1, iterationCount));
112
113 // validate
114
115 unit_assert_operator_equal(9, test3.count()); // 0 2 5 8 11 14 17 20 23
119
120 if (os_) *os_ << endl;
121}
122
123
125{
126 if (os_) *os_ << "testCancel()\n";
127
129
130 CancelListener cancelListener(12);
131 TestListener test3("test3");
132 TestListener test4("test4");
133 TestListener test6("test6");
134
135 registry.addListener(IterationListenerPtr(&cancelListener, nullDeallocate), 1);
138 registry.addListener(IterationListenerPtr(&test6, nullDeallocate), 5);
139
140 // typical use of IterationListenerRegistry, with proper Status_Cancel handling
141
142 bool canceled = false;
143
144 size_t iterationCount = 24;
145 for (size_t i=0; i<iterationCount; i++)
146 {
148 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(i, iterationCount));
149
150 // handle Status_Cancel
152 {
153 canceled = true;
154 break;
155 }
156 }
157
158 // implementations should send a final update on completion of the iteration
159
160 if (!canceled)
161 registry.broadcastUpdateMessage(IterationListener::UpdateMessage(iterationCount, iterationCount));
162
163 // validate
164
165 unit_assert(test3.count() == 5);
166 unit_assert(test4.count() == 4);
167 unit_assert(test6.count() == 3);
168
169 if (os_) *os_ << endl;
170}
171
172
174{
175 public:
176
177 virtual Status update(const UpdateMessage& updateMessage)
178 {
179 throw runtime_error("bad");
180 }
181};
182
183
185{
186 if (os_) *os_ << "testRemove()\n";
187
189
190 BadListener bad;
191 TestListener test3("test3");
192 TestListener test4("test4");
193
195
197 registry.addListener(badPtr, 1);
199
200 // sanity check -- verify that broadcast throws if BadListener is in the registry
201
202 bool caught = false;
203
204 try
205 {
207 }
208 catch (exception& e)
209 {
210 if (e.what() == string("bad")) caught = true;
211 }
212
213 unit_assert(caught);
214
215 // remove BadListener -- broadcast will throw if not removed properly
216
217 registry.removeListener(badPtr);
219
220 if (os_) *os_ << endl;
221}
222
223
225{
226 if (os_) *os_ << "testTime()\n";
227
229
230 TestListener test_iteration("test_iteration");
231 TestListener test_time("test_time");
232
233 registry.addListener(IterationListenerPtr(&test_iteration, nullDeallocate), 1000000);
234 registry.addListenerWithTimer(IterationListenerPtr(&test_time, nullDeallocate), 1.0);
235
236 time_t start;
237 time(&start);
238
239 const double iterationDuration = 5.0;
240 for (int i=0; ; i++)
241 {
242 time_t now;
243 time(&now);
244 if (difftime(now, start) > iterationDuration) break;
245
247 }
248
249 if (os_) *os_ << endl;
250}
251
252
253int main(int argc, char* argv[])
254{
255 TEST_PROLOG(argc, argv)
256
257 try
258 {
259 if (argc>1 && !strcmp(argv[1],"-v")) os_ = &cout;
260 test();
261 testCancel();
262 testRemove();
263 testTime();
264 }
265 catch (exception& e)
266 {
267 TEST_FAILED(e.what())
268 }
269 catch (...)
270 {
271 TEST_FAILED("Caught unknown exception.")
272 }
273
275}
276
277
void test4()
void test3()
int main(int argc, char *argv[])
void testTime()
void nullDeallocate(IterationListener *s)
void testRemove()
ostream * os_
void test()
void testCancel()
virtual Status update(const UpdateMessage &updateMessage)
virtual Status update(const UpdateMessage &updateMessage)
CancelListener(size_t cancelIndex)
virtual Status update(const UpdateMessage &updateMessage)
TestListener(const string &name)
interface to be implemented by clients who want progress callbacks
handles registration of IterationListeners and broadcast of update messages
void addListenerWithTimer(const IterationListenerPtr &listener, double timePeriod)
void addListener(const IterationListenerPtr &listener, size_t iterationPeriod)
IterationListener::Status broadcastUpdateMessage(const IterationListener::UpdateMessage &updateMessage) const
void removeListener(const IterationListenerPtr &listener)
boost::shared_ptr< IterationListener > IterationListenerPtr
#define unit_assert(x)
Definition unit.hpp:85
#define TEST_EPILOG
Definition unit.hpp:183
#define TEST_FAILED(x)
Definition unit.hpp:177
#define unit_assert_operator_equal(expected, actual)
Definition unit.hpp:92
#define TEST_PROLOG(argc, argv)
Definition unit.hpp:175