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

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

checkstyle: enable relevant whitespace checks and fix them

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