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

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

fix #9906 - fix reliance on default encoding

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