source: josm/trunk/test/functional/org/openstreetmap/josm/io/OsmServerBackreferenceReaderTest.java@ 2448

Last change on this file since 2448 was 2399, checked in by jttt, 14 years ago

Added map of primitives to dataset to make search by id faster
check if primitive already exist in addPrimitive and removePrimitive
use PrimitiveId instead of id + primitive type

File size: 19.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertNotNull;
6import static org.junit.Assert.fail;
7
8import java.io.File;
9import java.io.FileInputStream;
10import java.io.FileWriter;
11import java.io.IOException;
12import java.io.PrintWriter;
13import java.text.MessageFormat;
14import java.util.ArrayList;
15import java.util.HashSet;
16import java.util.Properties;
17import java.util.Set;
18import java.util.logging.Level;
19import java.util.logging.Logger;
20
21import org.junit.Before;
22import org.junit.BeforeClass;
23import org.junit.Test;
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.data.coor.LatLon;
26import org.openstreetmap.josm.data.osm.Changeset;
27import org.openstreetmap.josm.data.osm.DataSet;
28import org.openstreetmap.josm.data.osm.Node;
29import org.openstreetmap.josm.data.osm.OsmPrimitive;
30import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
31import org.openstreetmap.josm.data.osm.Relation;
32import org.openstreetmap.josm.data.osm.RelationMember;
33import org.openstreetmap.josm.data.osm.Way;
34import org.openstreetmap.josm.data.projection.Mercator;
35import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
36
37public class OsmServerBackreferenceReaderTest {
38 static private final Logger logger = Logger.getLogger(OsmServerBackreferenceReader.class.getName());
39
40 protected static Node lookupNode(DataSet ds, int i) {
41 for (Node n : ds.getNodes()) {
42 if (("node-" + i).equals(n.get("name"))) return n;
43 }
44 return null;
45 }
46
47
48 protected static Way lookupWay(DataSet ds, int i) {
49 for (Way w : ds.getWays()) {
50 if (("way-" + i).equals(w.get("name"))) return w;
51 }
52 return null;
53 }
54
55 protected static Relation lookupRelation(DataSet ds, int i) {
56 for (Relation r : ds.getRelations()) {
57 if (("relation-" + i).equals(r.get("name"))) return r;
58 }
59 return null;
60 }
61
62 protected static void populateTestDataSetWithNodes(DataSet ds) {
63 for (int i=0;i<100;i++) {
64 Node n = new Node(0);
65 n.setCoor(new LatLon(-36.6,47.6));
66 n.put("name", "node-"+i);
67 n.incomplete = false;
68 ds.addPrimitive(n);
69 }
70 }
71
72 protected static void populateTestDataSetWithWays(DataSet ds) {
73 for (int i=0;i<20;i++) {
74 Way w = new Way(0);
75 w.incomplete = false;
76 for (int j = 0; j < 10;j++) {
77 w.addNode(lookupNode(ds, i+j));
78 }
79 w.put("name", "way-"+i);
80 ds.addPrimitive(w);
81 }
82 }
83
84 protected static void populateTestDataSetWithRelations(DataSet ds) {
85 for (int i=0;i<10;i++) {
86 Relation r = new Relation(0);
87 r.incomplete = false;
88 r.put("name", "relation-" +i);
89 for (int j =0; j < 10; j++) {
90 RelationMember member = new RelationMember("node-" + j, lookupNode(ds, i + j));
91 r.addMember(member);
92 }
93 for (int j =0; j < 5; j++) {
94 RelationMember member = new RelationMember("way-" + j, lookupWay(ds, i + j));
95 r.addMember(member);
96 }
97 if (i > 5) {
98 for (int j =0; j < 3; j++) {
99 RelationMember member = new RelationMember("relation-" + j, lookupRelation(ds, j));
100 logger.info(MessageFormat.format("adding relation {0} to relation {1}", j, i));
101 r.addMember(member);
102 }
103 }
104 ds.addPrimitive(r);
105 }
106 }
107
108
109 protected static DataSet buildTestDataSet() {
110 DataSet ds = new DataSet();
111 ds.setVersion("0.6");
112
113 populateTestDataSetWithNodes(ds);
114 populateTestDataSetWithWays(ds);
115 populateTestDataSetWithRelations(ds);
116 return ds;
117 }
118
119 /**
120 * creates the dataset on the server.
121 *
122 * @param ds the data set
123 * @throws OsmTransferException
124 */
125 static public void createDataSetOnServer(DataSet ds) throws OsmTransferException {
126 logger.info("creating data set on the server ...");
127 ArrayList<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
128 primitives.addAll(ds.getNodes());
129 primitives.addAll(ds.getWays());
130 primitives.addAll(ds.getRelations());
131 OsmServerWriter writer = new OsmServerWriter();
132 Changeset cs = new Changeset();
133 writer.uploadOsm("0.6", primitives, cs, NullProgressMonitor.INSTANCE);
134 OsmApi.getOsmApi().closeChangeset(cs, NullProgressMonitor.INSTANCE);
135 }
136
137 static Properties testProperties;
138 static DataSet testDataSet;
139
140 @BeforeClass
141 public static void init() throws OsmTransferException, InterruptedException{
142 logger.info("initializing ...");
143 testProperties = new Properties();
144
145 // load properties
146 //
147 try {
148 testProperties.load(MultiFetchServerObjectReaderTest.class.getResourceAsStream("/test-functional-env.properties"));
149 } catch(Exception e){
150 logger.log(Level.SEVERE, MessageFormat.format("failed to load property file ''{0}''", "test-functional-env.properties"));
151 fail(MessageFormat.format("failed to load property file ''{0}''", "test-functional-env.properties"));
152 }
153
154 // check josm.home
155 //
156 String josmHome = testProperties.getProperty("josm.home");
157 if (josmHome == null) {
158 fail(MessageFormat.format("property ''{0}'' not set in test environment", "josm.home"));
159 } else {
160 File f = new File(josmHome);
161 if (! f.exists() || ! f.canRead()) {
162 fail(MessageFormat.format("property ''{0}'' points to ''{1}'' which is either not existing or not readable", "josm.home", josmHome));
163 }
164 }
165
166 // check temp output dir
167 //
168 String tempOutputDir = testProperties.getProperty("test.functional.tempdir");
169 if (tempOutputDir == null) {
170 fail(MessageFormat.format("property ''{0}'' not set in test environment", "test.functional.tempdir"));
171 } else {
172 File f = new File(tempOutputDir);
173 if (! f.exists() || ! f.isDirectory() || ! f.canWrite()) {
174 fail(MessageFormat.format("property ''{0}'' points to ''{1}'' which is either not existing, not a directory, or not writeable", "test.functional.tempdir", tempOutputDir));
175 }
176 }
177
178
179 // init preferences
180 //
181 System.setProperty("josm.home", josmHome);
182 Main.pref.init(false);
183 // don't use atomic upload, the test API server can't cope with large diff uploads
184 //
185 Main.pref.put("osm-server.atomic-upload", false);
186 Main.proj = new Mercator();
187
188 File dataSetCacheOutputFile = new File(tempOutputDir, MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
189
190 // make sure we don't upload to production
191 //
192 String url = OsmApi.getOsmApi().getBaseUrl().toLowerCase().trim();
193 if (url.startsWith("http://www.openstreetmap.org")
194 || url.startsWith("http://api.openstreetmap.org")) {
195 fail(MessageFormat.format("configured url ''{0}'' seems to be a productive url, aborting.", url));
196 }
197
198
199 String p = System.getProperties().getProperty("useCachedDataset");
200 if (p != null && Boolean.parseBoolean(p.trim().toLowerCase())) {
201 logger.info(MessageFormat.format("property ''{0}'' set, using cached dataset", "useCachedDataset"));
202 return;
203 }
204
205 logger.info(MessageFormat.format("property ''{0}'' not set to true, creating test dataset on the server. property is ''{1}''", "useCachedDataset", p));
206
207 // build and upload the test data set
208 //
209 logger.info("creating test data set ....");
210 testDataSet = buildTestDataSet();
211 logger.info("uploading test data set ...");
212 createDataSetOnServer(testDataSet);
213
214 PrintWriter pw = null;
215 try {
216 pw = new PrintWriter(
217 new FileWriter(dataSetCacheOutputFile)
218 );
219 } catch(IOException e) {
220 fail(MessageFormat.format("failed to open file ''{0}'' for writing", dataSetCacheOutputFile.toString()));
221 }
222 logger.info(MessageFormat.format("caching test data set in ''{0}'' ...", dataSetCacheOutputFile.toString()));
223 OsmWriter w = new OsmWriter(pw, false, testDataSet.getVersion());
224 w.header();
225 w.writeDataSources(testDataSet);
226 w.writeContent(testDataSet);
227 w.footer();
228 w.close();
229 pw.close();
230 }
231
232 private DataSet ds;
233
234 @Before
235 public void setUp() throws IOException, IllegalDataException {
236 File f = new File(testProperties.getProperty("test.functional.tempdir"), MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
237 logger.info(MessageFormat.format("reading cached dataset ''{0}''", f.toString()));
238 ds = new DataSet();
239 FileInputStream fis = new FileInputStream(f);
240 ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
241 fis.close();
242 }
243
244 @Test
245 public void testBackrefrenceForNode() throws OsmTransferException {
246 Node n = lookupNode(ds, 0);
247 assertNotNull(n);
248 Way w = lookupWay(ds, 0);
249 assertNotNull(w);
250
251 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
252 reader.setReadFull(false);
253 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
254 assertEquals(10, referers.getNodes().size());
255 assertEquals(1, referers.getWays().size());
256 assertEquals(0, referers.getRelations().size());
257 for (Way way : referers.getWays()) {
258 assertEquals(w.getId(), way.getId());
259 assertEquals(false, way.incomplete);
260 }
261 }
262
263 @Test
264 public void testBackrefrenceForNode_Full() throws OsmTransferException {
265 Node n = lookupNode(ds, 0);
266 assertNotNull(n);
267 Way w = lookupWay(ds, 0);
268 assertNotNull(w);
269
270 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
271 reader.setReadFull(true);
272 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
273 assertEquals(10, referers.getNodes().size());
274 assertEquals(1, referers.getWays().size());
275 assertEquals(0, referers.getRelations().size());
276 for (Way way : referers.getWays()) {
277 assertEquals(w.getId(), way.getId());
278 assertEquals(false, way.incomplete);
279 assertEquals(10, w.getNodesCount());
280 }
281 }
282
283 @Test
284 public void testBackrefrenceForWay() throws OsmTransferException {
285 Way w = lookupWay(ds, 1);
286 assertNotNull(w);
287 // way with name "way-1" is referred to by two relations
288 //
289
290 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
291 reader.setReadFull(false);
292 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
293 assertEquals(0, referers.getNodes().size()); // no nodes loaded
294 assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations
295 for (Way w1 : referers.getWays()) {
296 assertEquals(true, w1.incomplete);
297 }
298 assertEquals(2, referers.getRelations().size()); // two relations referring to w
299
300 Relation r = lookupRelation(referers, 0);
301 assertNotNull(r);
302 assertEquals(false, r.incomplete);
303 r = lookupRelation(referers, 1);
304 assertEquals(false, r.incomplete);
305 }
306
307 @Test
308 public void testBackrefrenceForWay_Full() throws OsmTransferException {
309 Way w = lookupWay(ds, 1);
310 assertNotNull(w);
311 // way with name "way-1" is referred to by two relations
312 //
313
314 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
315 reader.setReadFull(true);
316 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
317 assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations
318 for (Way w1 : referers.getWays()) {
319 assertEquals(false, w1.incomplete);
320 }
321 assertEquals(2, referers.getRelations().size()); // two relations referring to
322 Set<Long> expectedNodeIds = new HashSet<Long>();
323 for (Way way : referers.getWays()) {
324 Way orig = (Way) ds.getPrimitiveById(way);
325 for (Node n : orig.getNodes()) {
326 expectedNodeIds.add(n.getId());
327 }
328 }
329 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
330 for (Node n : referers.getNodes()) {
331 assertEquals(true, expectedNodeIds.contains(n.getId()));
332 }
333
334 Relation r = lookupRelation(referers, 0);
335 assertNotNull(r);
336 assertEquals(false, r.incomplete);
337 r = lookupRelation(referers, 1);
338 assertEquals(false, r.incomplete);
339 }
340
341 @Test
342 public void testBackrefrenceForRelation() throws OsmTransferException {
343 Relation r = lookupRelation(ds, 1);
344 assertNotNull(r);
345 // way with name "relation-1" is referred to by four relations:
346 // relation-6, relation-7, relation-8, relation-9
347 //
348
349 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
350 reader.setReadFull(false);
351 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
352
353 Set<Long> referringRelationsIds = new HashSet<Long>();
354 r = lookupRelation(referers, 6);
355 assertNotNull(r);
356 assertEquals(false, r.incomplete);
357 referringRelationsIds.add(r.getId());
358 r = lookupRelation(referers, 7);
359 assertNotNull(r);
360 assertEquals(false, r.incomplete);
361 referringRelationsIds.add(r.getId());
362 r = lookupRelation(referers, 8);
363 assertNotNull(r);
364 assertEquals(false, r.incomplete);
365 referringRelationsIds.add(r.getId());
366 r = lookupRelation(referers, 9);
367 assertNotNull(r);
368 assertEquals(false, r.incomplete);
369 referringRelationsIds.add(r.getId());
370
371 for (Relation r1 : referers.getRelations()) {
372 if (!referringRelationsIds.contains(r1.getId())) {
373 assertEquals(true, r1.incomplete);
374 }
375 }
376
377 // make sure we read all ways referred to by parent relations. These
378 // ways are incomplete after reading.
379 //
380 Set<Long> expectedWayIds = new HashSet<Long>();
381 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
382 if (m.isWay()) {
383 expectedWayIds.add(m.getMember().getId());
384 }
385 }
386 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
387 if (m.isWay()) {
388 expectedWayIds.add(m.getMember().getId());
389 }
390 }
391 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
392 if (m.isWay()) {
393 expectedWayIds.add(m.getMember().getId());
394 }
395 }
396 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
397 if (m.isWay()) {
398 expectedWayIds.add(m.getMember().getId());
399 }
400 }
401
402 assertEquals(expectedWayIds.size(), referers.getWays().size());
403 for (Way w1 : referers.getWays()) {
404 assertEquals(true, expectedWayIds.contains(w1.getId()));
405 assertEquals(true, w1.incomplete);
406 }
407
408 // make sure we didn't read any nodes
409 //
410 assertEquals(0, referers.getNodes().size());
411 }
412
413 protected Set<Long> getNodeIdsInWay(Way way) {
414 HashSet<Long> ret = new HashSet<Long>();
415 if (way == null)return ret;
416 for (Node n: way.getNodes()) {
417 ret.add(n.getId());
418 }
419 return ret;
420 }
421
422 protected Set<Long> getNodeIdsInRelation(Relation r) {
423 HashSet<Long> ret = new HashSet<Long>();
424 if (r == null) return ret;
425 for (RelationMember m: r.getMembers()) {
426 if (m.isNode()) {
427 ret.add(m.getMember().getId());
428 } else if (m.isWay()) {
429 ret.addAll(getNodeIdsInWay(m.getWay()));
430 } else if (m.isRelation()) {
431 ret.addAll(getNodeIdsInRelation(m.getRelation()));
432 }
433 }
434 return ret;
435 }
436
437 @Test
438 public void testBackrefrenceForRelation_Full() throws OsmTransferException {
439 Relation r = lookupRelation(ds, 1);
440 assertNotNull(r);
441 // way with name "relation-1" is referred to by four relations:
442 // relation-6, relation-7, relation-8, relation-9
443 //
444
445 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
446 reader.setReadFull(true);
447 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
448
449 Set<Long> referringRelationsIds = new HashSet<Long>();
450 r = lookupRelation(referers, 6);
451 assertNotNull(r);
452 assertEquals(false, r.incomplete);
453 referringRelationsIds.add(r.getId());
454 r = lookupRelation(referers, 7);
455 assertNotNull(r);
456 assertEquals(false, r.incomplete);
457 referringRelationsIds.add(r.getId());
458 r = lookupRelation(referers, 8);
459 assertNotNull(r);
460 assertEquals(false, r.incomplete);
461 referringRelationsIds.add(r.getId());
462 r = lookupRelation(referers, 9);
463 assertNotNull(r);
464 assertEquals(false, r.incomplete);
465 referringRelationsIds.add(r.getId());
466
467 // all relations are fully loaded
468 //
469 for (Relation r1 : referers.getRelations()) {
470 assertEquals(false, r1.incomplete);
471 }
472
473 // make sure we read all ways referred to by parent relations. These
474 // ways are completely read after reading the relations
475 //
476 Set<Long> expectedWayIds = new HashSet<Long>();
477 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
478 if (m.isWay()) {
479 expectedWayIds.add(m.getMember().getId());
480 }
481 }
482 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
483 if (m.isWay()) {
484 expectedWayIds.add(m.getMember().getId());
485 }
486 }
487 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
488 if (m.isWay()) {
489 expectedWayIds.add(m.getMember().getId());
490 }
491 }
492 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
493 if (m.isWay()) {
494 expectedWayIds.add(m.getMember().getId());
495 }
496 }
497 for (long id : expectedWayIds) {
498 Way w = (Way) referers.getPrimitiveById(id, OsmPrimitiveType.WAY);
499 assertNotNull(w);
500 assertEquals(false, w.incomplete);
501 }
502
503 Set<Long> expectedNodeIds = new HashSet<Long>();
504 for (int i = 6; i < 10; i++) {
505 Relation r1 = lookupRelation(ds, i);
506 expectedNodeIds.addAll(getNodeIdsInRelation(r1));
507 }
508
509 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
510 for (Node n : referers.getNodes()) {
511 assertEquals(true, expectedNodeIds.contains(n.getId()));
512 }
513 }
514}
Note: See TracBrowser for help on using the repository browser.