Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
model-port-registry-test.cpp
Go to the documentation of this file.
1/*
2 ModelPortRegistry(Test) - verify handling of model ports
3
4 Copyright (C)
5 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
19#include "lib/test/run.hpp"
23#include "steam/asset/pipe.hpp"
24#include "common/query.hpp"
25#include "lib/util.hpp"
26
27
28namespace steam {
29namespace fixture {
30namespace test {
31
33 using util::isnil;
34
35 using asset::Pipe;
36 using asset::PPipe;
37 using asset::Struct;
38 using asset::Timeline;
39 using asset::PTimeline;
40 using mobject::ModelPort;
41 using lumiera::Query;
42
43 using PID = asset::ID<Pipe>;
44 using TID = asset::ID<Struct>;
45
47
48 using mobject::LUMIERA_ERROR_INVALID_MODEL_PORT;
49 using mobject::LUMIERA_ERROR_UNCONNECTED_MODEL_PORT;
50
51
52 namespace { // test environment
53
54 inline PID
55 getPipe (string id)
56 {
57 return Pipe::query ("id("+id+")");
58 }
59
60 inline TID
61 getTimeline (string id)
62 {
63 return asset::Struct::retrieve (Query<Timeline> ("id("+id+")"))->getID();
64 }
65
67 {
70
73 : registry_()
74 , previous_(ModelPortRegistry::setActiveInstance (registry_))
75 { }
76
79 {
80 if (previous_)
81 ModelPortRegistry::setActiveInstance (*previous_);
82 else
83 ModelPortRegistry::shutdown();
84 }
85 };
86 }
87
88
89
90
91 /*****************************************************************************/
102 class ModelPortRegistry_test : public Test
103 {
104
105 virtual void
106 run (Arg)
107 {
108 TestContext ctx;
109
110 fabricating_ModelPorts (ctx.registry_);
112 transactionalSwitch (ctx.registry_);
113 }
114
115
116 void
118 {
119 /* == some Assets to play with == */
120 PID pipeA = getPipe ("pipeA");
121 PID pipeB = getPipe ("pipeB");
122 TID someTimeline = getTimeline ("some_test_Timeline");
123
124 // start out with defining some new model ports......
125 MPDescriptor p1 = registry.definePort (pipeA, someTimeline);
126 MPDescriptor p2 = registry.definePort (pipeB, someTimeline);
127
128 CHECK (registry.contains (pipeA));
129 CHECK (registry.contains (pipeB));
130
131 VERIFY_ERROR (DUPLICATE_MODEL_PORT, registry.definePort(pipeB, someTimeline) );
132 CHECK (registry.contains (pipeB));
133
134 CHECK (pipeA == p1.id());
135 CHECK (pipeB == p2.id());
136 CHECK (someTimeline == p1.holder());
137 CHECK (someTimeline == p2.holder());
138
139 registry.commit();
140 }
141
142
143 void
145 {
146 PID pipeA = getPipe ("pipeA");
147 PID pipeB = getPipe ("pipeB");
148 PID pipeWC = getPipe ("WCpipe");
149
150 ModelPort mp1(pipeA);
151 ModelPort mp2(pipeB);
152
153 VERIFY_ERROR (INVALID_MODEL_PORT, ModelPort unbefitting(pipeWC) );
154
155 ModelPort mp1x(pipeA); // can be created multiple times
156 ModelPort mp2x(mp1x); // can be copied at will
157 ModelPort mpNull; // can be default constructed (->unconnected)
158
159 CHECK (mp1);
160 CHECK (mp2);
161 CHECK (mp1x);
162 CHECK (mp2x);
163 CHECK (!mpNull); // bool check verifies setup and connected state
164
165 CHECK ( ModelPort::exists (pipeA)); // this is the same check, but invoked just with an pipe-ID
166 CHECK ( ModelPort::exists (pipeB));
167 CHECK (!ModelPort::exists (pipeWC));
168
169 CHECK (mp1 == mp1x);
170 CHECK (!isSameObject (mp1, mp1x));
171 CHECK (mp1 != mp2);
172 CHECK (mp2 != mp1);
173 CHECK (mp1 != mpNull);
174 CHECK (mp2 != mpNull);
175
176 CHECK (mp1.pipe() == pipeA);
177 CHECK (mp2.pipe() == pipeB);
178 CHECK (mp1x.pipe() == pipeA);
179 VERIFY_ERROR (UNCONNECTED_MODEL_PORT, mpNull.pipe()); // any further operations on an unconnected port will throw
180 VERIFY_ERROR (UNCONNECTED_MODEL_PORT, mpNull.holder());
181
182 CHECK (mp1.streamType() == pipeA.streamType());
183 }
184
185
186 void
188 {
189 PID pipeA = getPipe ("pipeA");
190 PID pipeB = getPipe ("pipeB");
191 PID pipeWC = getPipe ("WCpipe");
192
193 CHECK ( ModelPort::exists (pipeB));
194 CHECK (!ModelPort::exists (pipeWC));
195
196 CHECK (ModelPort::exists (pipeA));
197 CHECK (registry.contains (pipeA));
198 registry.remove (pipeA);
199 CHECK (!registry.contains (pipeA)); // removed from the current (pending) transaction
200 CHECK ( ModelPort::exists (pipeA)); // but not yet publicly visible
201
202 // now create a new and differing definition of port A
203 TID anotherTimeline = getTimeline ("another_test_Timeline");
204 MPDescriptor p1 = registry.definePort (pipeA, anotherTimeline);
205 CHECK (registry.contains (pipeA));
206 CHECK (anotherTimeline == p1.holder());
207 CHECK (ModelPort(pipeA).holder() != anotherTimeline);
208
209 registry.remove (pipeB); // some more wired definitions
210 registry.definePort (pipeWC, anotherTimeline);
211 CHECK (!registry.contains (pipeB));
212 CHECK ( registry.contains (pipeWC));
213 CHECK ( ModelPort::exists (pipeB));
214 CHECK (!ModelPort::exists (pipeWC));
215 CHECK ( registry.isRegistered (pipeB)); // this is the same as ModelPort::exists
216 CHECK (!registry.isRegistered (pipeWC)); //
217 // Note: pending transaction not yet committed
218 ModelPort portA(pipeA); // ...... thus the changes aren't reflected to client code
219 ModelPort portB(pipeB);
220 VERIFY_ERROR (INVALID_MODEL_PORT, ModelPort ineptly(pipeWC));
221 CHECK (portA);
222 CHECK (portB);
223 CHECK (portA.pipe() == pipeA);
224 CHECK (portB.pipe() == pipeB);
225 CHECK (portA.holder() != anotherTimeline);
226
227 registry.commit();
228 CHECK ( ModelPort::exists (pipeA)); // now all our changes got publicly visible
229 CHECK (!ModelPort::exists (pipeB));
230 CHECK ( ModelPort::exists (pipeWC));
231 CHECK ( portA);
232 CHECK (!portB);
233 CHECK (portA.holder() == anotherTimeline);
234 CHECK (portA.pipe() == pipeA);
235 VERIFY_ERROR (INVALID_MODEL_PORT, portB.pipe());
236
237 ModelPort pwc(pipeWC); // now clients may also use the now officially promoted new port
238 CHECK (pwc);
239 CHECK (pwc.pipe() == pipeWC);
240 CHECK (pwc.holder() == anotherTimeline);
241
242 // Next: doing several changes,
243 // but finally *not* committing them...
244 CHECK ( registry.contains (pipeA));
245 CHECK (!registry.contains (pipeB));
246 CHECK ( registry.contains (pipeWC));
247 registry.remove (pipeA);
248 registry.clear(); // remove everything from the pending transaction
249 CHECK (!registry.contains (pipeA));
250 CHECK (!registry.contains (pipeB));
251 CHECK (!registry.contains (pipeWC));
252
253 registry.definePort (pipeB, anotherTimeline);
254 CHECK ( registry.contains (pipeB));
255 CHECK (!portB); // not committed and thus not visible
256 CHECK (portA);
257 CHECK (pwc);
258
259 registry.rollback();
260 CHECK ( registry.contains (pipeA)); // no effect to the officially visible state
261 CHECK (!registry.contains (pipeB));
262 CHECK ( registry.contains (pipeWC));
263
264 VERIFY_ERROR(INVALID_MODEL_PORT, registry.get(pipeB) );
265 CHECK (!portB);
266 }
267 };
268
269
271 LAUNCHER (ModelPortRegistry_test, "unit fixture session builder");
272
273
274
275}}} // namespace steam::fixture::test
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition p.hpp:77
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition query.hpp:254
StreamType::ID streamType() const
allows to fetch the StreamType directly just from a Pipe-ID
Definition pipe.hpp:121
thin wrapper around a size_t hash ID used as primary key for all Asset objects.
Definition asset.hpp:98
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition pipe.hpp:72
static PPipe query(string const &properties)
convenience shortcut for retrieving default configured pipes
Definition pipe.cpp:57
key abstraction: structural asset Created automatically as a sideeffect of building the structure of ...
Definition struct.hpp:105
static StructFactory retrieve
storage for the static StructFactory instance
Definition struct.hpp:107
ModelPortDescriptor records are used as actual storage within the model port registration table; they...
Management facility for tracking model ports.
ModelPortDescriptor const & definePort(PID pipe, StID element_exposing_this_port)
create and register a new model port entry, within the pending transaction
void rollback()
discard pending changes.
ModelPortDescriptor const & get(PID) const
basic access operation: access the descriptor of a currently valid model port.
void remove(PID)
remove a model port entry from the pending transaction
bool contains(PID) const
does the transaction currently being built already contain a model port registration for the given ID...
void clear()
schedule removal of all registry contents.
void commit()
activate pending model port changes.
void fabricating_ModelPorts(ModelPortRegistry &registry)
Handle designating a point within the model, where actually output data can be pulled.
ID< asset::Struct > holder() const
access the timeline (or similar structural element) holding a global pipe which corresponds to this m...
static bool exists(ID< asset::Pipe >)
check if the global model port registration contains a mapping for the given pipe-ID
ID< asset::Pipe > pipe() const
access the Pipe (ID) of the global model port registered with the ID underlying this model port.
StreamType::ID streamType() const
convenience shortcut to access the stream type associated with the pipe-ID corresponding to this mode...
Mutation and management facility for model ports within the builder.
ModelPortRegistry::ModelPortDescriptor const & MPDescriptor
Steam-Layer implementation namespace root.
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
bool isnil(lib::time::Duration const &dur)
A "processing pipe" represented as Asset.
Basic and generic representation of an internal query.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Top level structural element within the session.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...