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

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

Checkstyle 6.19: enable SingleSpaceSeparator and fix violations

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