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

Last change on this file since 8926 was 8926, checked in by Don-vip, 9 years ago

javadoc fixes

  • Property svn:eol-style set to native
File size: 22.0 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.assertFalse;
6import static org.junit.Assert.assertNotNull;
7import static org.junit.Assert.assertTrue;
8import static org.junit.Assert.fail;
9
10import java.io.File;
11import java.io.FileInputStream;
12import java.io.FileNotFoundException;
13import java.io.FileOutputStream;
14import java.io.IOException;
15import java.io.OutputStreamWriter;
16import java.io.PrintWriter;
17import java.nio.charset.StandardCharsets;
18import java.text.MessageFormat;
19import java.util.HashSet;
20import java.util.Set;
21import java.util.logging.Logger;
22
23import org.junit.Before;
24import org.junit.BeforeClass;
25import org.junit.Test;
26import org.openstreetmap.josm.JOSMFixture;
27import org.openstreetmap.josm.Main;
28import org.openstreetmap.josm.actions.upload.CyclicUploadDependencyException;
29import org.openstreetmap.josm.data.APIDataSet;
30import org.openstreetmap.josm.data.coor.LatLon;
31import org.openstreetmap.josm.data.osm.Changeset;
32import org.openstreetmap.josm.data.osm.DataSet;
33import org.openstreetmap.josm.data.osm.Node;
34import org.openstreetmap.josm.data.osm.OsmPrimitive;
35import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
36import org.openstreetmap.josm.data.osm.Relation;
37import org.openstreetmap.josm.data.osm.RelationMember;
38import org.openstreetmap.josm.data.osm.Way;
39import org.openstreetmap.josm.data.projection.Projections;
40import org.openstreetmap.josm.gui.io.UploadStrategy;
41import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
42import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
43
44/**
45 * Reads primitives referring to a particular primitive (ways including a node, relations referring to a relation)
46 * @since 1806
47 */
48public class OsmServerBackreferenceReaderTest {
49 private static final Logger logger = Logger.getLogger(OsmServerBackreferenceReader.class.getName());
50
51 protected static Node lookupNode(DataSet ds, int i) {
52 for (Node n : ds.getNodes()) {
53 if (("node-" + i).equals(n.get("name"))) return n;
54 }
55 fail("Cannot find node "+i);
56 return null;
57 }
58
59 protected static Way lookupWay(DataSet ds, int i) {
60 for (Way w : ds.getWays()) {
61 if (("way-" + i).equals(w.get("name"))) return w;
62 }
63 fail("Cannot find way "+i);
64 return null;
65 }
66
67 protected static Relation lookupRelation(DataSet ds, int i) {
68 for (Relation r : ds.getRelations()) {
69 if (("relation-" + i).equals(r.get("name"))) return r;
70 }
71 fail("Cannot find relation "+i);
72 return null;
73 }
74
75 protected static void populateTestDataSetWithNodes(DataSet ds) {
76 for (int i = 0; i < 100; i++) {
77 Node n = new Node();
78 n.setCoor(new LatLon(-36.6, 47.6));
79 n.put("name", "node-"+i);
80 ds.addPrimitive(n);
81 }
82 }
83
84 protected static void populateTestDataSetWithWays(DataSet ds) {
85 for (int i = 0; i < 20; i++) {
86 Way w = new Way();
87 for (int j = 0; j < 10; j++) {
88 w.addNode(lookupNode(ds, i+j));
89 }
90 w.put("name", "way-"+i);
91 ds.addPrimitive(w);
92 }
93 }
94
95 protected static void populateTestDataSetWithRelations(DataSet ds) {
96 for (int i = 0; i < 10; i++) {
97 Relation r = new Relation();
98 r.put("name", "relation-" +i);
99 for (int j = 0; j < 10; j++) {
100 RelationMember member = new RelationMember("node-" + j, lookupNode(ds, i + j));
101 r.addMember(member);
102 }
103 for (int j = 0; j < 5; j++) {
104 RelationMember member = new RelationMember("way-" + j, lookupWay(ds, i + j));
105 r.addMember(member);
106 }
107 if (i > 5) {
108 for (int j = 0; j < 3; j++) {
109 RelationMember member = new RelationMember("relation-" + j, lookupRelation(ds, j));
110 logger.info(MessageFormat.format("adding relation {0} to relation {1}", j, i));
111 r.addMember(member);
112 }
113 }
114 ds.addPrimitive(r);
115 }
116 }
117
118 protected static DataSet buildTestDataSet() {
119 DataSet ds = new DataSet();
120 ds.setVersion("0.6");
121
122 populateTestDataSetWithNodes(ds);
123 populateTestDataSetWithWays(ds);
124 populateTestDataSetWithRelations(ds);
125 return ds;
126 }
127
128 /**
129 * creates the dataset on the server.
130 *
131 * @param ds the data set
132 * @throws OsmTransferException if something goes wrong
133 * @throws CyclicUploadDependencyException if a cyclic dependency is detected
134 */
135 public static void createDataSetOnServer(APIDataSet ds) throws OsmTransferException, CyclicUploadDependencyException {
136 logger.info("creating data set on the server ...");
137 ds.adjustRelationUploadOrder();
138 OsmServerWriter writer = new OsmServerWriter();
139 Changeset cs = new Changeset();
140 writer.uploadOsm(
141 new UploadStrategySpecification().setStrategy(UploadStrategy.SINGLE_REQUEST_STRATEGY),
142 ds.getPrimitives(), cs, NullProgressMonitor.INSTANCE);
143 OsmApi.getOsmApi().closeChangeset(cs, NullProgressMonitor.INSTANCE);
144 }
145
146 static DataSet testDataSet;
147
148 /**
149 * Setup test.
150 * @throws OsmTransferException if something goes wrong
151 * @throws CyclicUploadDependencyException if a cyclic dependency is detected
152 */
153 @BeforeClass
154 public static void setUpBeforeClass() throws OsmTransferException, CyclicUploadDependencyException {
155 logger.info("initializing ...");
156
157 JOSMFixture.createFunctionalTestFixture().init();
158
159 // don't use atomic upload, the test API server can't cope with large diff uploads
160 //
161 Main.pref.put("osm-server.atomic-upload", false);
162 Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
163 Main.logLevel = 4;
164
165 File dataSetCacheOutputFile = new File(System.getProperty("java.io.tmpdir"),
166 MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
167
168 String p = System.getProperty("useCachedDataset");
169 if (p != null && Boolean.parseBoolean(p.trim().toLowerCase())) {
170 logger.info(MessageFormat.format("property ''{0}'' set, using cached dataset", "useCachedDataset"));
171 return;
172 }
173
174 logger.info(MessageFormat.format(
175 "property ''{0}'' not set to true, creating test dataset on the server. property is ''{1}''", "useCachedDataset", p));
176
177 // build and upload the test data set
178 //
179 logger.info("creating test data set ....");
180 testDataSet = buildTestDataSet();
181 logger.info("uploading test data set ...");
182 createDataSetOnServer(new APIDataSet(testDataSet));
183
184 try (
185 PrintWriter pw = new PrintWriter(
186 new OutputStreamWriter(new FileOutputStream(dataSetCacheOutputFile), StandardCharsets.UTF_8)
187 )) {
188 logger.info(MessageFormat.format("caching test data set in ''{0}'' ...", dataSetCacheOutputFile.toString()));
189 try (OsmWriter w = new OsmWriter(pw, false, testDataSet.getVersion())) {
190 w.header();
191 w.writeDataSources(testDataSet);
192 w.writeContent(testDataSet);
193 w.footer();
194 }
195 } catch (IOException e) {
196 fail(MessageFormat.format("failed to open file ''{0}'' for writing", dataSetCacheOutputFile.toString()));
197 }
198 }
199
200 private DataSet ds;
201
202 /**
203 * Setup test.
204 * @throws IOException if any I/O error occurs
205 * @throws IllegalDataException if an error was found while parsing the OSM data
206 * @throws FileNotFoundException if the dataset file cannot be found
207 */
208 @Before
209 public void setUp() throws IOException, IllegalDataException, FileNotFoundException {
210 File f = new File(System.getProperty("java.io.tmpdir"), MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
211 logger.info(MessageFormat.format("reading cached dataset ''{0}''", f.toString()));
212 ds = new DataSet();
213 try (FileInputStream fis = new FileInputStream(f)) {
214 ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
215 }
216 }
217
218 @Test
219 public void testBackreferenceForNode() throws OsmTransferException {
220 Node n = lookupNode(ds, 0);
221 assertNotNull(n);
222 Way w = lookupWay(ds, 0);
223 assertNotNull(w);
224
225 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
226 reader.setReadFull(false);
227 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
228 printNumberOfPrimitives(referers);
229
230 Set<Long> expectedNodeIds = new HashSet<>();
231 Set<Long> expectedWayIds = new HashSet<>();
232 Set<Long> expectedRelationIds = new HashSet<>();
233
234 for (OsmPrimitive ref : n.getReferrers()) {
235 if (ref instanceof Way) {
236 expectedWayIds.add(ref.getId());
237 expectedNodeIds.addAll(getNodeIdsInWay((Way) ref));
238 } else if (ref instanceof Relation) {
239 expectedRelationIds.add(ref.getId());
240 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, false));
241 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
242 }
243 }
244
245 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
246 assertEquals(expectedWayIds.size(), referers.getWays().size());
247 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
248
249 for (Node node : referers.getNodes()) {
250 assertTrue(expectedNodeIds.contains(node.getId()));
251 assertFalse(node.isIncomplete());
252 }
253
254 for (Way way : referers.getWays()) {
255 assertTrue(expectedWayIds.contains(way.getId()));
256 assertEquals(n.getReferrers().contains(way), !way.isIncomplete());
257 }
258
259 for (Relation relation : referers.getRelations()) {
260 assertTrue(expectedRelationIds.contains(relation.getId()));
261 assertFalse(relation.isIncomplete());
262 }
263 }
264
265 private void printNumberOfPrimitives(DataSet referers) {
266 System.out.println("#nodes=" + referers.getNodes().size() +
267 " #ways=" + referers.getWays().size() +
268 " #relations=" + referers.getRelations().size());
269 }
270
271 @Test
272 public void testBackreferenceForNode_Full() throws OsmTransferException {
273 Node n = lookupNode(ds, 0);
274 assertNotNull(n);
275
276 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
277 reader.setReadFull(true);
278 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
279 printNumberOfPrimitives(referers);
280
281 Set<Long> expectedNodeIds = new HashSet<>();
282 Set<Long> expectedWayIds = new HashSet<>();
283 Set<Long> expectedRelationIds = new HashSet<>();
284 for (OsmPrimitive ref : n.getReferrers()) {
285 if (ref instanceof Way) {
286 expectedWayIds.add(ref.getId());
287 expectedNodeIds.addAll(getNodeIdsInWay((Way) ref));
288 } else if (ref instanceof Relation) {
289 expectedRelationIds.add(ref.getId());
290 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, true));
291 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, true));
292 }
293 }
294
295 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
296 assertEquals(expectedWayIds.size(), referers.getWays().size());
297 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
298
299 for (Node node : referers.getNodes()) {
300 assertTrue(expectedNodeIds.contains(node.getId()));
301 assertFalse(node.isIncomplete());
302 }
303
304 for (Way way : referers.getWays()) {
305 assertTrue(expectedWayIds.contains(way.getId()));
306 assertFalse(way.isIncomplete());
307 }
308
309 for (Relation relation : referers.getRelations()) {
310 assertTrue(expectedRelationIds.contains(relation.getId()));
311 assertFalse(relation.isIncomplete());
312 }
313 }
314
315 @Test
316 public void testBackreferenceForWay() throws OsmTransferException {
317 Way w = lookupWay(ds, 1);
318 assertNotNull(w);
319 // way with name "way-1" is referred to by two relations
320 //
321
322 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
323 reader.setReadFull(false);
324 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
325 printNumberOfPrimitives(referers);
326
327 Set<Long> expectedNodeIds = new HashSet<>();
328 Set<Long> expectedWayIds = new HashSet<>();
329 Set<Long> expectedRelationIds = new HashSet<>();
330
331 for (OsmPrimitive ref : w.getReferrers()) {
332 if (ref instanceof Relation) {
333 expectedRelationIds.add(ref.getId());
334 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, false));
335 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
336 }
337 }
338
339 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
340 assertEquals(expectedWayIds.size(), referers.getWays().size());
341 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
342
343 for (Way w1 : referers.getWays()) {
344 assertTrue(w1.isIncomplete());
345 }
346 assertEquals(2, referers.getRelations().size()); // two relations referring to w
347
348 Relation r = lookupRelation(referers, 0);
349 assertNotNull(r);
350 assertFalse(r.isIncomplete());
351 r = lookupRelation(referers, 1);
352 assertFalse(r.isIncomplete());
353 }
354
355 @Test
356 public void testBackreferenceForWay_Full() throws OsmTransferException {
357 Way w = lookupWay(ds, 1);
358 assertNotNull(w);
359 // way with name "way-1" is referred to by two relations
360 //
361
362 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
363 reader.setReadFull(true);
364 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
365 assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations
366 for (Way w1 : referers.getWays()) {
367 assertFalse(w1.isIncomplete());
368 }
369 assertEquals(2, referers.getRelations().size()); // two relations referring to
370 Set<Long> expectedNodeIds = new HashSet<>();
371 for (Way way : referers.getWays()) {
372 Way orig = (Way) ds.getPrimitiveById(way);
373 for (Node n : orig.getNodes()) {
374 expectedNodeIds.add(n.getId());
375 }
376 }
377 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
378 for (Node n : referers.getNodes()) {
379 assertTrue(expectedNodeIds.contains(n.getId()));
380 }
381
382 Relation r = lookupRelation(referers, 0);
383 assertNotNull(r);
384 assertFalse(r.isIncomplete());
385 r = lookupRelation(referers, 1);
386 assertFalse(r.isIncomplete());
387 }
388
389 @Test
390 public void testBackreferenceForRelation() throws OsmTransferException {
391 Relation r = lookupRelation(ds, 1);
392 assertNotNull(r);
393 // way with name "relation-1" is referred to by four relations:
394 // relation-6, relation-7, relation-8, relation-9
395 //
396
397 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
398 reader.setReadFull(false);
399 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
400 printNumberOfPrimitives(referers);
401
402 Set<Long> referringRelationsIds = new HashSet<>();
403 Relation r6 = lookupRelation(referers, 6);
404 assertNotNull(r6);
405 assertFalse(r6.isIncomplete());
406 referringRelationsIds.add(r6.getId());
407 Relation r7 = lookupRelation(referers, 7);
408 assertNotNull(r7);
409 assertFalse(r7.isIncomplete());
410 referringRelationsIds.add(r7.getId());
411 Relation r8 = lookupRelation(referers, 8);
412 assertNotNull(r8);
413 assertFalse(r8.isIncomplete());
414 referringRelationsIds.add(r8.getId());
415 Relation r9 = lookupRelation(referers, 9);
416 assertNotNull(r9);
417 assertFalse(r9.isIncomplete());
418 referringRelationsIds.add(r9.getId());
419
420 for (Relation r1 : referers.getRelations()) {
421 if (!referringRelationsIds.contains(r1.getId())) {
422 assertTrue(r1.isIncomplete());
423 }
424 }
425
426 // make sure we read all ways referred to by parent relations. These
427 // ways are incomplete after reading.
428 //
429 Set<Long> expectedWayIds = new HashSet<>();
430 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
431 if (m.isWay()) {
432 expectedWayIds.add(m.getMember().getId());
433 }
434 }
435 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
436 if (m.isWay()) {
437 expectedWayIds.add(m.getMember().getId());
438 }
439 }
440 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
441 if (m.isWay()) {
442 expectedWayIds.add(m.getMember().getId());
443 }
444 }
445 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
446 if (m.isWay()) {
447 expectedWayIds.add(m.getMember().getId());
448 }
449 }
450
451 assertEquals(expectedWayIds.size(), referers.getWays().size());
452 for (Way w1 : referers.getWays()) {
453 assertTrue(expectedWayIds.contains(w1.getId()));
454 assertTrue(w1.isIncomplete());
455 }
456
457 // make sure we read all nodes referred to by parent relations.
458 Set<Long> expectedNodeIds = new HashSet<>();
459 for (OsmPrimitive ref : r.getReferrers()) {
460 if (ref instanceof Relation) {
461 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
462 }
463 }
464 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
465 }
466
467 protected static Set<Long> getNodeIdsInWay(Way way) {
468 HashSet<Long> ret = new HashSet<>();
469 if (way == null) return ret;
470 for (Node n: way.getNodes()) {
471 ret.add(n.getId());
472 }
473 return ret;
474 }
475
476 protected static Set<Long> getNodeIdsInRelation(Relation r, boolean children) {
477 HashSet<Long> ret = new HashSet<>();
478 if (r == null) return ret;
479 for (RelationMember m: r.getMembers()) {
480 if (m.isNode()) {
481 ret.add(m.getMember().getId());
482 } else if (m.isWay() && children) {
483 ret.addAll(getNodeIdsInWay(m.getWay()));
484 } else if (m.isRelation() && children) {
485 ret.addAll(getNodeIdsInRelation(m.getRelation(), true));
486 }
487 }
488 return ret;
489 }
490
491 protected static Set<Long> getWayIdsInRelation(Relation r, boolean children) {
492 HashSet<Long> ret = new HashSet<>();
493 if (r == null) return ret;
494 for (RelationMember m: r.getMembers()) {
495 if (m.isWay()) {
496 ret.add(m.getMember().getId());
497 } else if (m.isRelation() && children) {
498 ret.addAll(getWayIdsInRelation(m.getRelation(), true));
499 }
500 }
501 return ret;
502 }
503
504 @Test
505 public void testBackreferenceForRelation_Full() throws OsmTransferException {
506 Relation r = lookupRelation(ds, 1);
507 assertNotNull(r);
508 // way with name "relation-1" is referred to by four relations:
509 // relation-6, relation-7, relation-8, relation-9
510 //
511
512 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
513 reader.setReadFull(true);
514 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
515
516 Set<Long> referringRelationsIds = new HashSet<>();
517 r = lookupRelation(referers, 6);
518 assertNotNull(r);
519 assertFalse(r.isIncomplete());
520 referringRelationsIds.add(r.getId());
521 r = lookupRelation(referers, 7);
522 assertNotNull(r);
523 assertFalse(r.isIncomplete());
524 referringRelationsIds.add(r.getId());
525 r = lookupRelation(referers, 8);
526 assertNotNull(r);
527 assertFalse(r.isIncomplete());
528 referringRelationsIds.add(r.getId());
529 r = lookupRelation(referers, 9);
530 assertNotNull(r);
531 assertFalse(r.isIncomplete());
532 referringRelationsIds.add(r.getId());
533
534 // all relations are fully loaded
535 //
536 for (Relation r1 : referers.getRelations()) {
537 assertFalse(r1.isIncomplete());
538 }
539
540 // make sure we read all ways referred to by parent relations. These
541 // ways are completely read after reading the relations
542 //
543 Set<Long> expectedWayIds = new HashSet<>();
544 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
545 if (m.isWay()) {
546 expectedWayIds.add(m.getMember().getId());
547 }
548 }
549 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
550 if (m.isWay()) {
551 expectedWayIds.add(m.getMember().getId());
552 }
553 }
554 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
555 if (m.isWay()) {
556 expectedWayIds.add(m.getMember().getId());
557 }
558 }
559 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
560 if (m.isWay()) {
561 expectedWayIds.add(m.getMember().getId());
562 }
563 }
564 for (long id : expectedWayIds) {
565 Way w = (Way) referers.getPrimitiveById(id, OsmPrimitiveType.WAY);
566 assertNotNull(w);
567 assertFalse(w.isIncomplete());
568 }
569
570 Set<Long> expectedNodeIds = new HashSet<>();
571 for (int i = 6; i < 10; i++) {
572 Relation r1 = lookupRelation(ds, i);
573 expectedNodeIds.addAll(getNodeIdsInRelation(r1, true));
574 }
575
576 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
577 for (Node n : referers.getNodes()) {
578 assertTrue(expectedNodeIds.contains(n.getId()));
579 }
580 }
581}
Note: See TracBrowser for help on using the repository browser.