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

Last change on this file since 9704 was 9374, checked in by simon04, 8 years ago

see #7612 - use basic authentication for unit tests

  • 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 Main.pref.put("osm-server.auth-method", "basic");
160
161 // don't use atomic upload, the test API server can't cope with large diff uploads
162 //
163 Main.pref.put("osm-server.atomic-upload", false);
164 Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
165 Main.logLevel = 4;
166
167 File dataSetCacheOutputFile = new File(System.getProperty("java.io.tmpdir"),
168 MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
169
170 String p = System.getProperty("useCachedDataset");
171 if (p != null && Boolean.parseBoolean(p.trim().toLowerCase())) {
172 logger.info(MessageFormat.format("property ''{0}'' set, using cached dataset", "useCachedDataset"));
173 return;
174 }
175
176 logger.info(MessageFormat.format(
177 "property ''{0}'' not set to true, creating test dataset on the server. property is ''{1}''", "useCachedDataset", p));
178
179 // build and upload the test data set
180 //
181 logger.info("creating test data set ....");
182 testDataSet = buildTestDataSet();
183 logger.info("uploading test data set ...");
184 createDataSetOnServer(new APIDataSet(testDataSet));
185
186 try (
187 PrintWriter pw = new PrintWriter(
188 new OutputStreamWriter(new FileOutputStream(dataSetCacheOutputFile), StandardCharsets.UTF_8)
189 )) {
190 logger.info(MessageFormat.format("caching test data set in ''{0}'' ...", dataSetCacheOutputFile.toString()));
191 try (OsmWriter w = new OsmWriter(pw, false, testDataSet.getVersion())) {
192 w.header();
193 w.writeDataSources(testDataSet);
194 w.writeContent(testDataSet);
195 w.footer();
196 }
197 } catch (IOException e) {
198 fail(MessageFormat.format("failed to open file ''{0}'' for writing", dataSetCacheOutputFile.toString()));
199 }
200 }
201
202 private DataSet ds;
203
204 /**
205 * Setup test.
206 * @throws IOException if any I/O error occurs
207 * @throws IllegalDataException if an error was found while parsing the OSM data
208 * @throws FileNotFoundException if the dataset file cannot be found
209 */
210 @Before
211 public void setUp() throws IOException, IllegalDataException, FileNotFoundException {
212 File f = new File(System.getProperty("java.io.tmpdir"), MultiFetchServerObjectReaderTest.class.getName() + ".dataset");
213 logger.info(MessageFormat.format("reading cached dataset ''{0}''", f.toString()));
214 ds = new DataSet();
215 try (FileInputStream fis = new FileInputStream(f)) {
216 ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
217 }
218 }
219
220 @Test
221 public void testBackreferenceForNode() throws OsmTransferException {
222 Node n = lookupNode(ds, 0);
223 assertNotNull(n);
224 Way w = lookupWay(ds, 0);
225 assertNotNull(w);
226
227 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
228 reader.setReadFull(false);
229 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
230 printNumberOfPrimitives(referers);
231
232 Set<Long> expectedNodeIds = new HashSet<>();
233 Set<Long> expectedWayIds = new HashSet<>();
234 Set<Long> expectedRelationIds = new HashSet<>();
235
236 for (OsmPrimitive ref : n.getReferrers()) {
237 if (ref instanceof Way) {
238 expectedWayIds.add(ref.getId());
239 expectedNodeIds.addAll(getNodeIdsInWay((Way) ref));
240 } else if (ref instanceof Relation) {
241 expectedRelationIds.add(ref.getId());
242 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, false));
243 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
244 }
245 }
246
247 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
248 assertEquals(expectedWayIds.size(), referers.getWays().size());
249 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
250
251 for (Node node : referers.getNodes()) {
252 assertTrue(expectedNodeIds.contains(node.getId()));
253 assertFalse(node.isIncomplete());
254 }
255
256 for (Way way : referers.getWays()) {
257 assertTrue(expectedWayIds.contains(way.getId()));
258 assertEquals(n.getReferrers().contains(way), !way.isIncomplete());
259 }
260
261 for (Relation relation : referers.getRelations()) {
262 assertTrue(expectedRelationIds.contains(relation.getId()));
263 assertFalse(relation.isIncomplete());
264 }
265 }
266
267 private void printNumberOfPrimitives(DataSet referers) {
268 System.out.println("#nodes=" + referers.getNodes().size() +
269 " #ways=" + referers.getWays().size() +
270 " #relations=" + referers.getRelations().size());
271 }
272
273 @Test
274 public void testBackreferenceForNode_Full() throws OsmTransferException {
275 Node n = lookupNode(ds, 0);
276 assertNotNull(n);
277
278 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n);
279 reader.setReadFull(true);
280 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
281 printNumberOfPrimitives(referers);
282
283 Set<Long> expectedNodeIds = new HashSet<>();
284 Set<Long> expectedWayIds = new HashSet<>();
285 Set<Long> expectedRelationIds = new HashSet<>();
286 for (OsmPrimitive ref : n.getReferrers()) {
287 if (ref instanceof Way) {
288 expectedWayIds.add(ref.getId());
289 expectedNodeIds.addAll(getNodeIdsInWay((Way) ref));
290 } else if (ref instanceof Relation) {
291 expectedRelationIds.add(ref.getId());
292 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, true));
293 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, true));
294 }
295 }
296
297 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
298 assertEquals(expectedWayIds.size(), referers.getWays().size());
299 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
300
301 for (Node node : referers.getNodes()) {
302 assertTrue(expectedNodeIds.contains(node.getId()));
303 assertFalse(node.isIncomplete());
304 }
305
306 for (Way way : referers.getWays()) {
307 assertTrue(expectedWayIds.contains(way.getId()));
308 assertFalse(way.isIncomplete());
309 }
310
311 for (Relation relation : referers.getRelations()) {
312 assertTrue(expectedRelationIds.contains(relation.getId()));
313 assertFalse(relation.isIncomplete());
314 }
315 }
316
317 @Test
318 public void testBackreferenceForWay() throws OsmTransferException {
319 Way w = lookupWay(ds, 1);
320 assertNotNull(w);
321 // way with name "way-1" is referred to by two relations
322 //
323
324 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
325 reader.setReadFull(false);
326 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
327 printNumberOfPrimitives(referers);
328
329 Set<Long> expectedNodeIds = new HashSet<>();
330 Set<Long> expectedWayIds = new HashSet<>();
331 Set<Long> expectedRelationIds = new HashSet<>();
332
333 for (OsmPrimitive ref : w.getReferrers()) {
334 if (ref instanceof Relation) {
335 expectedRelationIds.add(ref.getId());
336 expectedWayIds.addAll(getWayIdsInRelation((Relation) ref, false));
337 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
338 }
339 }
340
341 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
342 assertEquals(expectedWayIds.size(), referers.getWays().size());
343 assertEquals(expectedRelationIds.size(), referers.getRelations().size());
344
345 for (Way w1 : referers.getWays()) {
346 assertTrue(w1.isIncomplete());
347 }
348 assertEquals(2, referers.getRelations().size()); // two relations referring to w
349
350 Relation r = lookupRelation(referers, 0);
351 assertNotNull(r);
352 assertFalse(r.isIncomplete());
353 r = lookupRelation(referers, 1);
354 assertFalse(r.isIncomplete());
355 }
356
357 @Test
358 public void testBackreferenceForWay_Full() throws OsmTransferException {
359 Way w = lookupWay(ds, 1);
360 assertNotNull(w);
361 // way with name "way-1" is referred to by two relations
362 //
363
364 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
365 reader.setReadFull(true);
366 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
367 assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations
368 for (Way w1 : referers.getWays()) {
369 assertFalse(w1.isIncomplete());
370 }
371 assertEquals(2, referers.getRelations().size()); // two relations referring to
372 Set<Long> expectedNodeIds = new HashSet<>();
373 for (Way way : referers.getWays()) {
374 Way orig = (Way) ds.getPrimitiveById(way);
375 for (Node n : orig.getNodes()) {
376 expectedNodeIds.add(n.getId());
377 }
378 }
379 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
380 for (Node n : referers.getNodes()) {
381 assertTrue(expectedNodeIds.contains(n.getId()));
382 }
383
384 Relation r = lookupRelation(referers, 0);
385 assertNotNull(r);
386 assertFalse(r.isIncomplete());
387 r = lookupRelation(referers, 1);
388 assertFalse(r.isIncomplete());
389 }
390
391 @Test
392 public void testBackreferenceForRelation() throws OsmTransferException {
393 Relation r = lookupRelation(ds, 1);
394 assertNotNull(r);
395 // way with name "relation-1" is referred to by four relations:
396 // relation-6, relation-7, relation-8, relation-9
397 //
398
399 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
400 reader.setReadFull(false);
401 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
402 printNumberOfPrimitives(referers);
403
404 Set<Long> referringRelationsIds = new HashSet<>();
405 Relation r6 = lookupRelation(referers, 6);
406 assertNotNull(r6);
407 assertFalse(r6.isIncomplete());
408 referringRelationsIds.add(r6.getId());
409 Relation r7 = lookupRelation(referers, 7);
410 assertNotNull(r7);
411 assertFalse(r7.isIncomplete());
412 referringRelationsIds.add(r7.getId());
413 Relation r8 = lookupRelation(referers, 8);
414 assertNotNull(r8);
415 assertFalse(r8.isIncomplete());
416 referringRelationsIds.add(r8.getId());
417 Relation r9 = lookupRelation(referers, 9);
418 assertNotNull(r9);
419 assertFalse(r9.isIncomplete());
420 referringRelationsIds.add(r9.getId());
421
422 for (Relation r1 : referers.getRelations()) {
423 if (!referringRelationsIds.contains(r1.getId())) {
424 assertTrue(r1.isIncomplete());
425 }
426 }
427
428 // make sure we read all ways referred to by parent relations. These
429 // ways are incomplete after reading.
430 //
431 Set<Long> expectedWayIds = new HashSet<>();
432 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
433 if (m.isWay()) {
434 expectedWayIds.add(m.getMember().getId());
435 }
436 }
437 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
438 if (m.isWay()) {
439 expectedWayIds.add(m.getMember().getId());
440 }
441 }
442 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
443 if (m.isWay()) {
444 expectedWayIds.add(m.getMember().getId());
445 }
446 }
447 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
448 if (m.isWay()) {
449 expectedWayIds.add(m.getMember().getId());
450 }
451 }
452
453 assertEquals(expectedWayIds.size(), referers.getWays().size());
454 for (Way w1 : referers.getWays()) {
455 assertTrue(expectedWayIds.contains(w1.getId()));
456 assertTrue(w1.isIncomplete());
457 }
458
459 // make sure we read all nodes referred to by parent relations.
460 Set<Long> expectedNodeIds = new HashSet<>();
461 for (OsmPrimitive ref : r.getReferrers()) {
462 if (ref instanceof Relation) {
463 expectedNodeIds.addAll(getNodeIdsInRelation((Relation) ref, false));
464 }
465 }
466 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
467 }
468
469 protected static Set<Long> getNodeIdsInWay(Way way) {
470 HashSet<Long> ret = new HashSet<>();
471 if (way == null) return ret;
472 for (Node n: way.getNodes()) {
473 ret.add(n.getId());
474 }
475 return ret;
476 }
477
478 protected static Set<Long> getNodeIdsInRelation(Relation r, boolean children) {
479 HashSet<Long> ret = new HashSet<>();
480 if (r == null) return ret;
481 for (RelationMember m: r.getMembers()) {
482 if (m.isNode()) {
483 ret.add(m.getMember().getId());
484 } else if (m.isWay() && children) {
485 ret.addAll(getNodeIdsInWay(m.getWay()));
486 } else if (m.isRelation() && children) {
487 ret.addAll(getNodeIdsInRelation(m.getRelation(), true));
488 }
489 }
490 return ret;
491 }
492
493 protected static Set<Long> getWayIdsInRelation(Relation r, boolean children) {
494 HashSet<Long> ret = new HashSet<>();
495 if (r == null) return ret;
496 for (RelationMember m: r.getMembers()) {
497 if (m.isWay()) {
498 ret.add(m.getMember().getId());
499 } else if (m.isRelation() && children) {
500 ret.addAll(getWayIdsInRelation(m.getRelation(), true));
501 }
502 }
503 return ret;
504 }
505
506 @Test
507 public void testBackreferenceForRelation_Full() throws OsmTransferException {
508 Relation r = lookupRelation(ds, 1);
509 assertNotNull(r);
510 // way with name "relation-1" is referred to by four relations:
511 // relation-6, relation-7, relation-8, relation-9
512 //
513
514 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r);
515 reader.setReadFull(true);
516 DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
517
518 Set<Long> referringRelationsIds = new HashSet<>();
519 r = lookupRelation(referers, 6);
520 assertNotNull(r);
521 assertFalse(r.isIncomplete());
522 referringRelationsIds.add(r.getId());
523 r = lookupRelation(referers, 7);
524 assertNotNull(r);
525 assertFalse(r.isIncomplete());
526 referringRelationsIds.add(r.getId());
527 r = lookupRelation(referers, 8);
528 assertNotNull(r);
529 assertFalse(r.isIncomplete());
530 referringRelationsIds.add(r.getId());
531 r = lookupRelation(referers, 9);
532 assertNotNull(r);
533 assertFalse(r.isIncomplete());
534 referringRelationsIds.add(r.getId());
535
536 // all relations are fully loaded
537 //
538 for (Relation r1 : referers.getRelations()) {
539 assertFalse(r1.isIncomplete());
540 }
541
542 // make sure we read all ways referred to by parent relations. These
543 // ways are completely read after reading the relations
544 //
545 Set<Long> expectedWayIds = new HashSet<>();
546 for (RelationMember m : lookupRelation(ds, 6).getMembers()) {
547 if (m.isWay()) {
548 expectedWayIds.add(m.getMember().getId());
549 }
550 }
551 for (RelationMember m : lookupRelation(ds, 7).getMembers()) {
552 if (m.isWay()) {
553 expectedWayIds.add(m.getMember().getId());
554 }
555 }
556 for (RelationMember m : lookupRelation(ds, 8).getMembers()) {
557 if (m.isWay()) {
558 expectedWayIds.add(m.getMember().getId());
559 }
560 }
561 for (RelationMember m : lookupRelation(ds, 9).getMembers()) {
562 if (m.isWay()) {
563 expectedWayIds.add(m.getMember().getId());
564 }
565 }
566 for (long id : expectedWayIds) {
567 Way w = (Way) referers.getPrimitiveById(id, OsmPrimitiveType.WAY);
568 assertNotNull(w);
569 assertFalse(w.isIncomplete());
570 }
571
572 Set<Long> expectedNodeIds = new HashSet<>();
573 for (int i = 6; i < 10; i++) {
574 Relation r1 = lookupRelation(ds, i);
575 expectedNodeIds.addAll(getNodeIdsInRelation(r1, true));
576 }
577
578 assertEquals(expectedNodeIds.size(), referers.getNodes().size());
579 for (Node n : referers.getNodes()) {
580 assertTrue(expectedNodeIds.contains(n.getId()));
581 }
582 }
583}
Note: See TracBrowser for help on using the repository browser.