test: refactor to use go 1.7 subtests

master
Oliver Tonnhofer 2018-06-05 21:04:02 +02:00
parent 32b80c2cdd
commit 160847e116
6 changed files with 1350 additions and 1303 deletions

View File

@ -10,53 +10,63 @@ import (
"github.com/omniscale/imposm3/geom/geos" "github.com/omniscale/imposm3/geom/geos"
) )
func TestAnyAny_Prepare(t *testing.T) { func TestAnyAny(t *testing.T) {
var err error if testing.Short() {
t.Skip("system test skipped with -test.short")
}
ts.dir, err = ioutil.TempDir("", "imposm_test") ts := importTestSuite{
if err != nil { name: "any_any",
t.Fatal(err)
} }
ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/any_any.pbf",
mappingFileName: "any_any_mapping.json",
}
ts.g = geos.NewGeos()
ts.db, err = sql.Open("postgres", "sslmode=disable") t.Run("Prepare", func(t *testing.T) {
if err != nil { var err error
t.Fatal(err)
}
ts.dropSchemas()
}
func TestAnyAny_Import(t *testing.T) { ts.dir, err = ioutil.TempDir("", "imposm_test")
if ts.tableExists(t, dbschemaImport, "osm_all") != false { if err != nil {
t.Fatalf("table osm_all exists in schema %s", dbschemaImport) t.Fatal(err)
} }
ts.importOsm(t) ts.config = importConfig{
ts.deployOsm(t) connection: "postgis://",
if ts.tableExists(t, dbschemaProduction, "osm_all") != true { cacheDir: ts.dir,
t.Fatalf("table osm_all does not exists in schema %s", dbschemaProduction) osmFileName: "build/any_any.pbf",
} mappingFileName: "any_any_mapping.json",
} }
ts.g = geos.NewGeos()
func TestAnyAny_InsertedNodes(t *testing.T) { ts.db, err = sql.Open("postgres", "sslmode=disable")
assertHstore(t, []checkElem{ if err != nil {
{"osm_all", 10000, "", nil}, // nodes without tags are not inserted t.Fatal(err)
{"osm_all", 10001, "*", map[string]string{"random": "tag"}}, }
{"osm_all", 10002, "*", map[string]string{"amenity": "shop"}}, ts.dropSchemas()
{"osm_all", 10003, "*", map[string]string{"random": "tag", "but": "mapped", "amenity": "shop"}}, })
{"osm_amenities", 10002, "*", map[string]string{"amenity": "shop"}},
{"osm_amenities", 10003, "*", map[string]string{"random": "tag", "but": "mapped", "amenity": "shop"}}, t.Run("Import", func(t *testing.T) {
if ts.tableExists(t, ts.dbschemaImport(), "osm_all") != false {
t.Fatalf("table osm_all exists in schema %s", ts.dbschemaImport())
}
ts.importOsm(t)
ts.deployOsm(t)
if ts.tableExists(t, ts.dbschemaProduction(), "osm_all") != true {
t.Fatalf("table osm_all does not exists in schema %s", ts.dbschemaProduction())
}
})
t.Run("InsertedNodes", func(t *testing.T) {
ts.assertHstore(t, []checkElem{
{"osm_all", 10000, "", nil}, // nodes without tags are not inserted
{"osm_all", 10001, "*", map[string]string{"random": "tag"}},
{"osm_all", 10002, "*", map[string]string{"amenity": "shop"}},
{"osm_all", 10003, "*", map[string]string{"random": "tag", "but": "mapped", "amenity": "shop"}},
{"osm_amenities", 10002, "*", map[string]string{"amenity": "shop"}},
{"osm_amenities", 10003, "*", map[string]string{"random": "tag", "but": "mapped", "amenity": "shop"}},
})
})
t.Run("Cleanup", func(t *testing.T) {
ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil {
t.Error(err)
}
}) })
} }
func TestAnyAny_Cleanup(t *testing.T) {
ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil {
t.Error(err)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -14,168 +14,178 @@ import (
"github.com/omniscale/imposm3/geom/geos" "github.com/omniscale/imposm3/geom/geos"
) )
func TestExpireTiles_Prepare(t *testing.T) { func TestExpireTiles(t *testing.T) {
var err error if testing.Short() {
t.Skip("system test skipped with -test.short")
ts.dir, err = ioutil.TempDir("", "imposm_test")
if err != nil {
t.Fatal(err)
} }
ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/expire_tiles.pbf",
mappingFileName: "expire_tiles_mapping.yml",
expireTileDir: filepath.Join(ts.dir, "expiretiles"),
}
ts.g = geos.NewGeos()
ts.db, err = sql.Open("postgres", "sslmode=disable") ts := importTestSuite{
if err != nil { name: "expire_tiles",
t.Fatal(err)
} }
ts.dropSchemas()
}
func TestExpireTiles_Import(t *testing.T) { t.Run("Prepare", func(t *testing.T) {
if ts.tableExists(t, dbschemaImport, "osm_roads") != false { var err error
t.Fatalf("table osm_roads exists in schema %s", dbschemaImport)
}
ts.importOsm(t)
ts.deployOsm(t)
if ts.tableExists(t, dbschemaProduction, "osm_roads") != true {
t.Fatalf("table osm_roads does not exists in schema %s", dbschemaProduction)
}
}
func TestExpireTiles_Elements(t *testing.T) { ts.dir, err = ioutil.TempDir("", "imposm_test")
assertRecords(t, []checkElem{ if err != nil {
{"osm_roads", 20151, "motorway", nil}, t.Fatal(err)
{"osm_roads", 20251, "motorway", nil}, }
{"osm_roads", 20351, "motorway", nil}, ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/expire_tiles.pbf",
mappingFileName: "expire_tiles_mapping.yml",
expireTileDir: filepath.Join(ts.dir, "expiretiles"),
}
ts.g = geos.NewGeos()
{"osm_buildings", -30191, "yes", nil}, ts.db, err = sql.Open("postgres", "sslmode=disable")
{"osm_buildings", -30291, "yes", nil}, if err != nil {
{"osm_buildings", -30391, "yes", nil}, t.Fatal(err)
{"osm_buildings", -30491, "yes", nil}, }
ts.dropSchemas()
}) })
}
func TestExpireTiles_Update(t *testing.T) { t.Run("Import", func(t *testing.T) {
ts.updateOsm(t, "build/expire_tiles.osc.gz") if ts.tableExists(t, ts.dbschemaImport(), "osm_roads") != false {
} t.Fatalf("table osm_roads exists in schema %s", ts.dbschemaImport())
}
ts.importOsm(t)
ts.deployOsm(t)
if ts.tableExists(t, ts.dbschemaProduction(), "osm_roads") != true {
t.Fatalf("table osm_roads does not exists in schema %s", ts.dbschemaProduction())
}
})
func TestExpireTiles_CheckExpireFile(t *testing.T) { t.Run("Elements", func(t *testing.T) {
files, err := filepath.Glob(filepath.Join(ts.config.expireTileDir, "*", "*.tiles")) ts.assertRecords(t, []checkElem{
if err != nil { {"osm_roads", 20151, "motorway", nil},
t.Fatal(err) {"osm_roads", 20251, "motorway", nil},
} {"osm_roads", 20351, "motorway", nil},
if len(files) != 1 {
t.Fatalf("expected one expire tile file, got: %v", files)
}
tiles, err := parseTileList(files[0])
if err != nil {
t.Error(err)
}
for _, test := range []struct { {"osm_buildings", -30191, "yes", nil},
reason string {"osm_buildings", -30291, "yes", nil},
tiles []tile {"osm_buildings", -30391, "yes", nil},
expire bool {"osm_buildings", -30491, "yes", nil},
}{ })
{"create node", []tile{{8328, 8146, 14}}, true}, })
{"modify node (old)", []tile{{8237, 8146, 14}}, true},
{"modify node (new)", []tile{{8237, 8237, 14}}, true},
{"modify node to unmapped (old)", []tile{{8373, 8146, 14}, {8374, 8146, 14}}, true},
{"modify node to unmapped (new)", []tile{{8373, 8146, 14}, {8374, 8146, 14}}, false},
{"delete node", []tile{{8282, 8146, 14}, {8283, 8146, 14}}, true},
{"delete way", []tile{{8283, 8100, 14}}, true}, t.Run("Update", func(t *testing.T) {
{"modify way", []tile{{8237, 8100, 14}}, true}, ts.updateOsm(t, "build/expire_tiles.osc.gz")
{"modify way from node (old)", []tile{{8328, 8100, 14}}, true}, })
{"modify way from node (new)", []tile{{8328, 8283, 14}}, true},
{"create way", []tile{{8374, 8100, 14}}, true},
{"create long way", []tile{{8419, 8100, 14}, {8420, 8100, 14}, {8421, 8100, 14}}, true},
{"modify relation", []tile{{8237, 8055, 14}}, true}, t.Run("CheckExpireFile", func(t *testing.T) {
{"delete relation", []tile{{8283, 8055, 14}}, true}, files, err := filepath.Glob(filepath.Join(ts.config.expireTileDir, "*", "*.tiles"))
{"modify relation from way", []tile{{8328, 8055, 14}}, true}, if err != nil {
{"modify relation from nodes (old)", []tile{{8374, 8055, 14}}, true}, t.Fatal(err)
{"modify relation from nodes (new)", []tile{{8374, 8328, 14}}, true}, }
{"create polygon (box)", []tile{ if len(files) != 1 {
{8237, 8007, 14}, t.Fatalf("expected one expire tile file, got: %v", files)
{8237, 8008, 14}, }
{8237, 8009, 14}, tiles, err := parseTileList(files[0])
{8238, 8007, 14}, if err != nil {
{8238, 8008, 14}, t.Error(err)
{8238, 8009, 14}, }
{8239, 8007, 14},
{8239, 8008, 14},
{8239, 8009, 14},
}, true},
{"create polygon (outline)", []tile{ for _, test := range []struct {
{8310, 8005, 14}, {8302, 7991, 14}, {8283, 7993, 14}, reason string
{8300, 8009, 14}, {8283, 8003, 14}, {8308, 8009, 14}, tiles []tile
{8310, 7995, 14}, {8285, 8009, 14}, {8288, 8009, 14}, expire bool
{8301, 8009, 14}, {8310, 8002, 14}, {8302, 8009, 14}, }{
{8310, 8003, 14}, {8286, 8009, 14}, {8300, 7991, 14}, {"create node", []tile{{8328, 8146, 14}}, true},
{8283, 7994, 14}, {8296, 8009, 14}, {8298, 8009, 14}, {"modify node (old)", []tile{{8237, 8146, 14}}, true},
{8310, 8009, 14}, {8283, 7999, 14}, {8283, 7992, 14}, {"modify node (new)", []tile{{8237, 8237, 14}}, true},
{8290, 7991, 14}, {8305, 8009, 14}, {8309, 7991, 14}, {"modify node to unmapped (old)", []tile{{8373, 8146, 14}, {8374, 8146, 14}}, true},
{8306, 7991, 14}, {8291, 7991, 14}, {8283, 7996, 14}, {"modify node to unmapped (new)", []tile{{8373, 8146, 14}, {8374, 8146, 14}}, false},
{8310, 7996, 14}, {8293, 7991, 14}, {8310, 8007, 14}, {"delete node", []tile{{8282, 8146, 14}, {8283, 8146, 14}}, true},
{8310, 8001, 14}, {8307, 8009, 14}, {8299, 8009, 14},
{8310, 7998, 14}, {8310, 7999, 14}, {8301, 7991, 14},
{8283, 7998, 14}, {8283, 8006, 14}, {8289, 8009, 14},
{8310, 8008, 14}, {8285, 7991, 14}, {8283, 8002, 14},
{8289, 7991, 14}, {8286, 7991, 14}, {8288, 7991, 14},
{8283, 8008, 14}, {8283, 8005, 14}, {8310, 7992, 14},
{8310, 8004, 14}, {8310, 7991, 14}, {8296, 7991, 14},
{8292, 7991, 14}, {8283, 8009, 14}, {8291, 8009, 14},
{8293, 8009, 14}, {8284, 8009, 14}, {8287, 7991, 14},
{8297, 8009, 14}, {8283, 8007, 14}, {8299, 7991, 14},
{8310, 7997, 14}, {8303, 8009, 14}, {8290, 8009, 14},
{8306, 8009, 14}, {8283, 7995, 14}, {8283, 8000, 14},
{8295, 8009, 14}, {8310, 8006, 14}, {8304, 8009, 14},
{8295, 7991, 14}, {8292, 8009, 14}, {8309, 8009, 14},
{8283, 8004, 14}, {8307, 7991, 14}, {8305, 7991, 14},
{8283, 8001, 14}, {8284, 7991, 14}, {8297, 7991, 14},
{8310, 7993, 14}, {8303, 7991, 14}, {8294, 8009, 14},
{8287, 8009, 14}, {8283, 7991, 14}, {8283, 7997, 14},
{8308, 7991, 14}, {8304, 7991, 14}, {8298, 7991, 14},
{8310, 8000, 14}, {8310, 7994, 14}, {8294, 7991, 14},
}, true},
} {
for _, coord := range test.tiles { {"delete way", []tile{{8283, 8100, 14}}, true},
if test.expire { {"modify way", []tile{{8237, 8100, 14}}, true},
if _, ok := tiles[coord]; !ok { {"modify way from node (old)", []tile{{8328, 8100, 14}}, true},
t.Errorf("missing expire tile for %s %v", test.reason, coord) {"modify way from node (new)", []tile{{8328, 8283, 14}}, true},
{"create way", []tile{{8374, 8100, 14}}, true},
{"create long way", []tile{{8419, 8100, 14}, {8420, 8100, 14}, {8421, 8100, 14}}, true},
{"modify relation", []tile{{8237, 8055, 14}}, true},
{"delete relation", []tile{{8283, 8055, 14}}, true},
{"modify relation from way", []tile{{8328, 8055, 14}}, true},
{"modify relation from nodes (old)", []tile{{8374, 8055, 14}}, true},
{"modify relation from nodes (new)", []tile{{8374, 8328, 14}}, true},
{"create polygon (box)", []tile{
{8237, 8007, 14},
{8237, 8008, 14},
{8237, 8009, 14},
{8238, 8007, 14},
{8238, 8008, 14},
{8238, 8009, 14},
{8239, 8007, 14},
{8239, 8008, 14},
{8239, 8009, 14},
}, true},
{"create polygon (outline)", []tile{
{8310, 8005, 14}, {8302, 7991, 14}, {8283, 7993, 14},
{8300, 8009, 14}, {8283, 8003, 14}, {8308, 8009, 14},
{8310, 7995, 14}, {8285, 8009, 14}, {8288, 8009, 14},
{8301, 8009, 14}, {8310, 8002, 14}, {8302, 8009, 14},
{8310, 8003, 14}, {8286, 8009, 14}, {8300, 7991, 14},
{8283, 7994, 14}, {8296, 8009, 14}, {8298, 8009, 14},
{8310, 8009, 14}, {8283, 7999, 14}, {8283, 7992, 14},
{8290, 7991, 14}, {8305, 8009, 14}, {8309, 7991, 14},
{8306, 7991, 14}, {8291, 7991, 14}, {8283, 7996, 14},
{8310, 7996, 14}, {8293, 7991, 14}, {8310, 8007, 14},
{8310, 8001, 14}, {8307, 8009, 14}, {8299, 8009, 14},
{8310, 7998, 14}, {8310, 7999, 14}, {8301, 7991, 14},
{8283, 7998, 14}, {8283, 8006, 14}, {8289, 8009, 14},
{8310, 8008, 14}, {8285, 7991, 14}, {8283, 8002, 14},
{8289, 7991, 14}, {8286, 7991, 14}, {8288, 7991, 14},
{8283, 8008, 14}, {8283, 8005, 14}, {8310, 7992, 14},
{8310, 8004, 14}, {8310, 7991, 14}, {8296, 7991, 14},
{8292, 7991, 14}, {8283, 8009, 14}, {8291, 8009, 14},
{8293, 8009, 14}, {8284, 8009, 14}, {8287, 7991, 14},
{8297, 8009, 14}, {8283, 8007, 14}, {8299, 7991, 14},
{8310, 7997, 14}, {8303, 8009, 14}, {8290, 8009, 14},
{8306, 8009, 14}, {8283, 7995, 14}, {8283, 8000, 14},
{8295, 8009, 14}, {8310, 8006, 14}, {8304, 8009, 14},
{8295, 7991, 14}, {8292, 8009, 14}, {8309, 8009, 14},
{8283, 8004, 14}, {8307, 7991, 14}, {8305, 7991, 14},
{8283, 8001, 14}, {8284, 7991, 14}, {8297, 7991, 14},
{8310, 7993, 14}, {8303, 7991, 14}, {8294, 8009, 14},
{8287, 8009, 14}, {8283, 7991, 14}, {8283, 7997, 14},
{8308, 7991, 14}, {8304, 7991, 14}, {8298, 7991, 14},
{8310, 8000, 14}, {8310, 7994, 14}, {8294, 7991, 14},
}, true},
} {
for _, coord := range test.tiles {
if test.expire {
if _, ok := tiles[coord]; !ok {
t.Errorf("missing expire tile for %s %v", test.reason, coord)
} else {
delete(tiles, coord)
}
} else { } else {
delete(tiles, coord) if _, ok := tiles[coord]; ok {
} t.Errorf("found expire tile for %s %v", test.reason, coord)
} else { }
if _, ok := tiles[coord]; ok {
t.Errorf("found expire tile for %s %v", test.reason, coord)
} }
} }
} }
}
if len(tiles) > 0 { if len(tiles) > 0 {
t.Errorf("found %d unexpected tiles", len(tiles)) t.Errorf("found %d unexpected tiles", len(tiles))
} }
for tile, _ := range tiles { for tile, _ := range tiles {
t.Errorf("unexpected tile expired: %v", tile) t.Errorf("unexpected tile expired: %v", tile)
} }
} })
func TestExpireTiles_Cleanup(t *testing.T) { t.Run("Cleanup", func(t *testing.T) {
ts.dropSchemas() ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil { if err := os.RemoveAll(ts.dir); err != nil {
t.Error(err) t.Error(err)
} }
})
} }
type tile struct { type tile struct {

View File

@ -21,12 +21,6 @@ import (
"github.com/omniscale/imposm3/import_" "github.com/omniscale/imposm3/import_"
) )
const (
dbschemaImport = "imposm_test_import"
dbschemaProduction = "imposm_test_production"
dbschemaBackup = "imposm_test_backup"
)
type importConfig struct { type importConfig struct {
connection string connection string
osmFileName string osmFileName string
@ -38,6 +32,7 @@ type importConfig struct {
type importTestSuite struct { type importTestSuite struct {
dir string dir string
name string
config importConfig config importConfig
db *sql.DB db *sql.DB
g *geos.Geos g *geos.Geos
@ -45,6 +40,10 @@ type importTestSuite struct {
const Missing = "" const Missing = ""
func (s *importTestSuite) dbschemaImport() string { return "imposm_test_" + s.name + "_import" }
func (s *importTestSuite) dbschemaProduction() string { return "imposm_test_" + s.name + "_production" }
func (s *importTestSuite) dbschemaBackup() string { return "imposm_test_" + s.name + "_backup" }
func (s *importTestSuite) importOsm(t *testing.T) { func (s *importTestSuite) importOsm(t *testing.T) {
importArgs := []string{ importArgs := []string{
"-connection", s.config.connection, "-connection", s.config.connection,
@ -53,7 +52,7 @@ func (s *importTestSuite) importOsm(t *testing.T) {
"-cachedir", s.config.cacheDir, "-cachedir", s.config.cacheDir,
"-diff", "-diff",
"-overwritecache", "-overwritecache",
"-dbschema-import", dbschemaImport, "-dbschema-import", s.dbschemaImport(),
// "-optimize", // "-optimize",
"-mapping", s.config.mappingFileName, "-mapping", s.config.mappingFileName,
"-quiet", "-quiet",
@ -75,9 +74,9 @@ func (s *importTestSuite) deployOsm(t *testing.T) {
"-deployproduction", "-deployproduction",
"-removebackup=false", "-removebackup=false",
"-connection", s.config.connection, "-connection", s.config.connection,
"-dbschema-import", dbschemaImport, "-dbschema-import", s.dbschemaImport(),
"-dbschema-production", dbschemaProduction, "-dbschema-production", s.dbschemaProduction(),
"-dbschema-backup", dbschemaBackup, "-dbschema-backup", s.dbschemaBackup(),
"-deployproduction", "-deployproduction",
"-mapping", s.config.mappingFileName, "-mapping", s.config.mappingFileName,
"-quiet", "-quiet",
@ -96,9 +95,9 @@ func (s *importTestSuite) revertDeployOsm(t *testing.T) {
"-deployproduction=false", "-deployproduction=false",
"-removebackup=false", "-removebackup=false",
"-connection", s.config.connection, "-connection", s.config.connection,
"-dbschema-import", dbschemaImport, "-dbschema-import", s.dbschemaImport(),
"-dbschema-production", dbschemaProduction, "-dbschema-production", s.dbschemaProduction(),
"-dbschema-backup", dbschemaBackup, "-dbschema-backup", s.dbschemaBackup(),
"-revertdeploy", "-revertdeploy",
"-deployproduction=false", "-deployproduction=false",
"-removebackup=false", "-removebackup=false",
@ -135,9 +134,9 @@ func (s *importTestSuite) removeBackupOsm(t *testing.T) {
"-deployproduction=false", "-deployproduction=false",
"-removebackup", "-removebackup",
"-connection", s.config.connection, "-connection", s.config.connection,
"-dbschema-import", dbschemaImport, "-dbschema-import", s.dbschemaImport(),
"-dbschema-production", dbschemaProduction, "-dbschema-production", s.dbschemaProduction(),
"-dbschema-backup", dbschemaBackup, "-dbschema-backup", s.dbschemaBackup(),
"-mapping", s.config.mappingFileName, "-mapping", s.config.mappingFileName,
"-quiet", "-quiet",
} }
@ -151,7 +150,7 @@ func (s *importTestSuite) updateOsm(t *testing.T, diffFile string) {
"-connection", s.config.connection, "-connection", s.config.connection,
"-cachedir", s.config.cacheDir, "-cachedir", s.config.cacheDir,
"-limitto", "clipping.geojson", "-limitto", "clipping.geojson",
"-dbschema-production", dbschemaProduction, "-dbschema-production", s.dbschemaProduction(),
"-mapping", s.config.mappingFileName, "-mapping", s.config.mappingFileName,
} }
if s.config.expireTileDir != "" { if s.config.expireTileDir != "" {
@ -164,15 +163,15 @@ func (s *importTestSuite) updateOsm(t *testing.T, diffFile string) {
func (s *importTestSuite) dropSchemas() { func (s *importTestSuite) dropSchemas() {
var err error var err error
_, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, dbschemaImport)) _, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, s.dbschemaImport()))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
_, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, dbschemaProduction)) _, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, s.dbschemaProduction()))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
_, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, dbschemaBackup)) _, err = s.db.Exec(fmt.Sprintf(`DROP SCHEMA IF EXISTS %s CASCADE`, s.dbschemaBackup()))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -208,7 +207,7 @@ func (s *importTestSuite) query(t *testing.T, table string, id int64, keys []str
} else { } else {
columns = "hstore(ARRAY[" + columns + "])" columns = "hstore(ARRAY[" + columns + "])"
} }
stmt := fmt.Sprintf(`SELECT osm_id, name, type, ST_AsText(geometry), %s FROM "%s"."%s" WHERE osm_id=$1`, columns, dbschemaProduction, table) stmt := fmt.Sprintf(`SELECT osm_id, name, type, ST_AsText(geometry), %s FROM "%s"."%s" WHERE osm_id=$1`, columns, s.dbschemaProduction(), table)
row := s.db.QueryRow(stmt, id) row := s.db.QueryRow(stmt, id)
r := record{} r := record{}
h := hstore.Hstore{} h := hstore.Hstore{}
@ -231,7 +230,7 @@ func (s *importTestSuite) query(t *testing.T, table string, id int64, keys []str
} }
func (s *importTestSuite) queryTags(t *testing.T, table string, id int64) record { func (s *importTestSuite) queryTags(t *testing.T, table string, id int64) record {
stmt := fmt.Sprintf(`SELECT osm_id, tags FROM "%s"."%s" WHERE osm_id=$1`, dbschemaProduction, table) stmt := fmt.Sprintf(`SELECT osm_id, tags FROM "%s"."%s" WHERE osm_id=$1`, s.dbschemaProduction(), table)
row := s.db.QueryRow(stmt, id) row := s.db.QueryRow(stmt, id)
r := record{} r := record{}
h := hstore.Hstore{} h := hstore.Hstore{}
@ -254,7 +253,7 @@ func (s *importTestSuite) queryTags(t *testing.T, table string, id int64) record
} }
func (s *importTestSuite) queryRows(t *testing.T, table string, id int64) []record { func (s *importTestSuite) queryRows(t *testing.T, table string, id int64) []record {
rows, err := s.db.Query(fmt.Sprintf(`SELECT osm_id, name, type, ST_AsText(geometry) FROM "%s"."%s" WHERE osm_id=$1 ORDER BY type, name, ST_GeometryType(geometry)`, dbschemaProduction, table), id) rows, err := s.db.Query(fmt.Sprintf(`SELECT osm_id, name, type, ST_AsText(geometry) FROM "%s"."%s" WHERE osm_id=$1 ORDER BY type, name, ST_GeometryType(geometry)`, s.dbschemaProduction(), table), id)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -270,7 +269,7 @@ func (s *importTestSuite) queryRows(t *testing.T, table string, id int64) []reco
} }
func (s *importTestSuite) queryRowsTags(t *testing.T, table string, id int64) []record { func (s *importTestSuite) queryRowsTags(t *testing.T, table string, id int64) []record {
rows, err := s.db.Query(fmt.Sprintf(`SELECT osm_id, ST_AsText(geometry), tags FROM "%s"."%s" WHERE osm_id=$1 ORDER BY ST_GeometryType(geometry)`, dbschemaProduction, table), id) rows, err := s.db.Query(fmt.Sprintf(`SELECT osm_id, ST_AsText(geometry), tags FROM "%s"."%s" WHERE osm_id=$1 ORDER BY ST_GeometryType(geometry)`, s.dbschemaProduction(), table), id)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -295,7 +294,7 @@ func (s *importTestSuite) queryRowsTags(t *testing.T, table string, id int64) []
} }
func (s *importTestSuite) queryGeom(t *testing.T, table string, id int64) *geos.Geom { func (s *importTestSuite) queryGeom(t *testing.T, table string, id int64) *geos.Geom {
stmt := fmt.Sprintf(`SELECT osm_id, ST_AsText(geometry) FROM "%s"."%s" WHERE osm_id=$1`, dbschemaProduction, table) stmt := fmt.Sprintf(`SELECT osm_id, ST_AsText(geometry) FROM "%s"."%s" WHERE osm_id=$1`, s.dbschemaProduction(), table)
row := s.db.QueryRow(stmt, id) row := s.db.QueryRow(stmt, id)
r := record{} r := record{}
if err := row.Scan(&r.id, &r.wkt); err != nil { if err := row.Scan(&r.id, &r.wkt); err != nil {
@ -315,7 +314,7 @@ func (s *importTestSuite) queryGeom(t *testing.T, table string, id int64) *geos.
} }
func (s *importTestSuite) queryDynamic(t *testing.T, table, where string) []map[string]string { func (s *importTestSuite) queryDynamic(t *testing.T, table, where string) []map[string]string {
stmt := fmt.Sprintf(`SELECT hstore(r) FROM (SELECT ST_AsText(geometry) AS wkt, * FROM "%s"."%s" WHERE %s) AS r`, dbschemaProduction, table, where) stmt := fmt.Sprintf(`SELECT hstore(r) FROM (SELECT ST_AsText(geometry) AS wkt, * FROM "%s"."%s" WHERE %s) AS r`, s.dbschemaProduction(), table, where)
rows, err := s.db.Query(stmt) rows, err := s.db.Query(stmt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -344,7 +343,7 @@ type checkElem struct {
tags map[string]string tags map[string]string
} }
func assertRecords(t *testing.T, elems []checkElem) { func (ts *importTestSuite) assertRecords(t *testing.T, elems []checkElem) {
for _, e := range elems { for _, e := range elems {
keys := make([]string, 0, len(e.tags)) keys := make([]string, 0, len(e.tags))
for k, _ := range e.tags { for k, _ := range e.tags {
@ -368,7 +367,7 @@ func assertRecords(t *testing.T, elems []checkElem) {
} }
} }
func assertHstore(t *testing.T, elems []checkElem) { func (ts *importTestSuite) assertHstore(t *testing.T, elems []checkElem) {
for _, e := range elems { for _, e := range elems {
r := ts.queryTags(t, e.table, e.id) r := ts.queryTags(t, e.table, e.id)
if e.osmType == "" { if e.osmType == "" {
@ -388,14 +387,14 @@ func assertHstore(t *testing.T, elems []checkElem) {
} }
} }
func assertGeomValid(t *testing.T, e checkElem) { func (ts *importTestSuite) assertGeomValid(t *testing.T, e checkElem) {
geom := ts.queryGeom(t, e.table, e.id) geom := ts.queryGeom(t, e.table, e.id)
if !ts.g.IsValid(geom) { if !ts.g.IsValid(geom) {
t.Fatalf("geometry of %d is invalid", e.id) t.Fatalf("geometry of %d is invalid", e.id)
} }
} }
func assertGeomArea(t *testing.T, e checkElem, expect float64) { func (ts *importTestSuite) assertGeomArea(t *testing.T, e checkElem, expect float64) {
geom := ts.queryGeom(t, e.table, e.id) geom := ts.queryGeom(t, e.table, e.id)
if !ts.g.IsValid(geom) { if !ts.g.IsValid(geom) {
t.Fatalf("geometry of %d is invalid", e.id) t.Fatalf("geometry of %d is invalid", e.id)
@ -406,7 +405,7 @@ func assertGeomArea(t *testing.T, e checkElem, expect float64) {
} }
} }
func assertGeomLength(t *testing.T, e checkElem, expect float64) { func (ts *importTestSuite) assertGeomLength(t *testing.T, e checkElem, expect float64) {
geom := ts.queryGeom(t, e.table, e.id) geom := ts.queryGeom(t, e.table, e.id)
if !ts.g.IsValid(geom) { if !ts.g.IsValid(geom) {
t.Fatalf("geometry of %d is invalid", e.id) t.Fatalf("geometry of %d is invalid", e.id)
@ -417,14 +416,14 @@ func assertGeomLength(t *testing.T, e checkElem, expect float64) {
} }
} }
func assertGeomType(t *testing.T, e checkElem, expect string) { func (ts *importTestSuite) assertGeomType(t *testing.T, e checkElem, expect string) {
actual := ts.g.Type(ts.queryGeom(t, e.table, e.id)) actual := ts.g.Type(ts.queryGeom(t, e.table, e.id))
if actual != expect { if actual != expect {
t.Errorf("expected %s geometry for %d, got %s", expect, e.id, actual) t.Errorf("expected %s geometry for %d, got %s", expect, e.id, actual)
} }
} }
func assertCachedWay(t *testing.T, c *cache.OSMCache, id int64) *element.Way { func (ts *importTestSuite) assertCachedWay(t *testing.T, c *cache.OSMCache, id int64) *element.Way {
way, err := c.Ways.GetWay(id) way, err := c.Ways.GetWay(id)
if err == cache.NotFound { if err == cache.NotFound {
t.Errorf("missing way %d", id) t.Errorf("missing way %d", id)
@ -437,7 +436,7 @@ func assertCachedWay(t *testing.T, c *cache.OSMCache, id int64) *element.Way {
return way return way
} }
func assertCachedNode(t *testing.T, c *cache.OSMCache, id int64) *element.Node { func (ts *importTestSuite) assertCachedNode(t *testing.T, c *cache.OSMCache, id int64) *element.Node {
node, err := c.Nodes.GetNode(id) node, err := c.Nodes.GetNode(id)
if err == cache.NotFound { if err == cache.NotFound {
node, err = c.Coords.GetCoord(id) node, err = c.Coords.GetCoord(id)

View File

@ -10,158 +10,168 @@ import (
"github.com/omniscale/imposm3/geom/geos" "github.com/omniscale/imposm3/geom/geos"
) )
func TestRouteRelation_Prepare(t *testing.T) { func TestRouteRelation(t *testing.T) {
var err error if testing.Short() {
t.Skip("system test skipped with -test.short")
}
ts.dir, err = ioutil.TempDir("", "imposm_test") ts := importTestSuite{
if err != nil { name: "route_relation",
t.Fatal(err)
} }
ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/route_relation.pbf",
mappingFileName: "route_relation_mapping.yml",
}
ts.g = geos.NewGeos()
ts.db, err = sql.Open("postgres", "sslmode=disable") t.Run("Prepare", func(t *testing.T) {
if err != nil { var err error
t.Fatal(err)
} ts.dir, err = ioutil.TempDir("", "imposm_test")
ts.dropSchemas() if err != nil {
} t.Fatal(err)
}
func TestRouteRelation_Import(t *testing.T) { ts.config = importConfig{
if ts.tableExists(t, dbschemaImport, "osm_routes") != false { connection: "postgis://",
t.Fatalf("table osm_routes exists in schema %s", dbschemaImport) cacheDir: ts.dir,
} osmFileName: "build/route_relation.pbf",
ts.importOsm(t) mappingFileName: "route_relation_mapping.yml",
if ts.tableExists(t, dbschemaImport, "osm_routes") != true { }
t.Fatalf("table osm_routes does not exists in schema %s", dbschemaImport) ts.g = geos.NewGeos()
}
} ts.db, err = sql.Open("postgres", "sslmode=disable")
if err != nil {
func TestRouteRelation_Deploy(t *testing.T) { t.Fatal(err)
ts.deployOsm(t) }
if ts.tableExists(t, dbschemaImport, "osm_routes") != false { ts.dropSchemas()
t.Fatalf("table osm_routes exists in schema %s", dbschemaImport) })
}
if ts.tableExists(t, dbschemaProduction, "osm_routes") != true { t.Run("Import", func(t *testing.T) {
t.Fatalf("table osm_routes does not exists in schema %s", dbschemaProduction) if ts.tableExists(t, ts.dbschemaImport(), "osm_routes") != false {
} t.Fatalf("table osm_routes exists in schema %s", ts.dbschemaImport())
} }
ts.importOsm(t)
func TestRouteRelation_RelationData(t *testing.T) { if ts.tableExists(t, ts.dbschemaImport(), "osm_routes") != true {
// check tags of relation t.Fatalf("table osm_routes does not exists in schema %s", ts.dbschemaImport())
r := ts.queryTags(t, "osm_routes", -100901) }
if r.tags["name"] != "Bus 301: A => B" { })
t.Error(r)
} t.Run("Deploy", func(t *testing.T) {
ts.deployOsm(t)
// check tags of master relation if ts.tableExists(t, ts.dbschemaImport(), "osm_routes") != false {
r = ts.queryTags(t, "osm_routes", -100911) t.Fatalf("table osm_routes exists in schema %s", ts.dbschemaImport())
if r.tags["name"] != "Bus 301" { }
t.Error(r) if ts.tableExists(t, ts.dbschemaProduction(), "osm_routes") != true {
} t.Fatalf("table osm_routes does not exists in schema %s", ts.dbschemaProduction())
} }
})
func TestRouteRelation_MemberUpdatedByNode1(t *testing.T) {
// check that member is updated after node was modified t.Run("RelationData", func(t *testing.T) {
rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -110901 AND member = 110101") // check tags of relation
if len(rows) != 1 { r := ts.queryTags(t, "osm_routes", -100901)
t.Fatal(rows) if r.tags["name"] != "Bus 301: A => B" {
} t.Error(r)
if rows[0]["name"] != "Stop" { }
t.Error(rows[0])
} // check tags of master relation
} r = ts.queryTags(t, "osm_routes", -100911)
if r.tags["name"] != "Bus 301" {
func TestRouteRelation_MemberGeomUpdated1(t *testing.T) { t.Error(r)
rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502") }
if len(rows) != 1 { })
t.Fatal(rows)
} t.Run("MemberUpdatedByNode1", func(t *testing.T) {
g := ts.g.FromWkt(rows[0]["wkt"]) // check that member is updated after node was modified
if math.Abs(g.Length()-111.32448543701321) > 0.00000001 { rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -110901 AND member = 110101")
t.Fatal(g.Length()) if len(rows) != 1 {
} t.Fatal(rows)
}
rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503") if rows[0]["name"] != "Stop" {
if len(rows) != 1 { t.Error(rows[0])
t.Fatal(rows) }
} })
if rows[0]["name"] != "" {
t.Error(rows[0]) t.Run("MemberGeomUpdated1", func(t *testing.T) {
} rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502")
} if len(rows) != 1 {
t.Fatal(rows)
func TestRouteRelation_NoRouteWithMissingMember(t *testing.T) { }
// current implementation: route members are all or nothing. g := ts.g.FromWkt(rows[0]["wkt"])
// if one member is missing, no member is imported if math.Abs(g.Length()-111.32448543701321) > 0.00000001 {
if r := ts.queryDynamic(t, "osm_route_members", "osm_id = -120901 AND member = 120101"); len(r) > 0 { t.Fatal(g.Length())
t.Error("found member from route with missing members") }
}
} rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503")
if len(rows) != 1 {
// ####################################################################### t.Fatal(rows)
}
func TestRouteRelation_Update(t *testing.T) { if rows[0]["name"] != "" {
ts.updateOsm(t, "./build/route_relation.osc.gz") t.Error(rows[0])
} }
})
// #######################################################################
t.Run("NoRouteWithMissingMember", func(t *testing.T) {
func TestRouteRelation_MemberGeomUpdated2(t *testing.T) { // current implementation: route members are all or nothing.
rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502") // if one member is missing, no member is imported
if len(rows) != 1 { if r := ts.queryDynamic(t, "osm_route_members", "osm_id = -120901 AND member = 120101"); len(r) > 0 {
t.Fatal(rows) t.Error("found member from route with missing members")
} }
g := ts.g.FromWkt(rows[0]["wkt"]) })
if math.Abs(g.Length()-184.97560221624542) > 0.00000001 {
t.Fatal(g.Length()) // #######################################################################
}
t.Run("Update", func(t *testing.T) {
// tag from member is updated ts.updateOsm(t, "build/route_relation.osc.gz")
rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503") })
if len(rows) != 1 {
t.Fatal(rows) // #######################################################################
}
if rows[0]["name"] != "new name" { t.Run("MemberGeomUpdated2", func(t *testing.T) {
t.Error(rows[0]) rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502")
} if len(rows) != 1 {
t.Fatal(rows)
// member is removed }
rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100512") g := ts.g.FromWkt(rows[0]["wkt"])
if len(rows) != 0 { if math.Abs(g.Length()-184.97560221624542) > 0.00000001 {
t.Fatal(rows) t.Fatal(g.Length())
} }
// role from member is updated // tag from member is updated
rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100102") rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503")
if len(rows) != 1 { if len(rows) != 1 {
t.Fatal(rows) t.Fatal(rows)
} }
if rows[0]["role"] != "halt" { if rows[0]["name"] != "new name" {
t.Error(rows[0]) t.Error(rows[0])
} }
} // member is removed
rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100512")
func TestRouteRelation_MemberUpdatedByNode2(t *testing.T) { if len(rows) != 0 {
// check that member is updated after node was modified t.Fatal(rows)
rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -110901 AND member = 110101") }
if len(rows) != 1 {
t.Fatal(rows) // role from member is updated
} rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100102")
if rows[0]["name"] != "Stop2" { if len(rows) != 1 {
t.Error(rows[0]) t.Fatal(rows)
} }
} if rows[0]["role"] != "halt" {
t.Error(rows[0])
func TestRouteRelation_Cleanup(t *testing.T) { }
ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil { })
t.Error(err)
} t.Run("MemberUpdatedByNode2", func(t *testing.T) {
// check that member is updated after node was modified
rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -110901 AND member = 110101")
if len(rows) != 1 {
t.Fatal(rows)
}
if rows[0]["name"] != "Stop2" {
t.Error(rows[0])
}
})
t.Run("Cleanup", func(t *testing.T) {
ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil {
t.Error(err)
}
})
} }

View File

@ -13,195 +13,205 @@ import (
const RelOffset = -1e17 const RelOffset = -1e17
func TestSingleTable_Prepare(t *testing.T) { func TestSingleTable(t *testing.T) {
var err error if testing.Short() {
t.Skip("system test skipped with -test.short")
ts.dir, err = ioutil.TempDir("", "imposm_test")
if err != nil {
t.Fatal(err)
}
ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/single_table.pbf",
mappingFileName: "single_table_mapping.json",
}
ts.g = geos.NewGeos()
ts.db, err = sql.Open("postgres", "sslmode=disable")
if err != nil {
t.Fatal(err)
}
ts.dropSchemas()
}
func TestSingleTable_Import(t *testing.T) {
if ts.tableExists(t, dbschemaImport, "osm_all") != false {
t.Fatalf("table osm_all exists in schema %s", dbschemaImport)
}
ts.importOsm(t)
if ts.tableExists(t, dbschemaImport, "osm_all") != true {
t.Fatalf("table osm_all does not exists in schema %s", dbschemaImport)
}
}
func TestSingleTable_Deploy(t *testing.T) {
ts.deployOsm(t)
if ts.tableExists(t, dbschemaImport, "osm_all") != false {
t.Fatalf("table osm_all exists in schema %s", dbschemaImport)
}
if ts.tableExists(t, dbschemaProduction, "osm_all") != true {
t.Fatalf("table osm_all does not exists in schema %s", dbschemaProduction)
}
}
func TestSingleTable_NonMappedNodeIsMissing(t *testing.T) {
// Node without mapped tags is missing.
cache := ts.cache(t)
defer cache.Close()
assertCachedNode(t, cache, 10001)
assertHstore(t, []checkElem{
{"osm_all", 10001, Missing, nil},
})
}
func TestSingleTable_MappedNode(t *testing.T) {
// Node is stored with all tags.
cache := ts.cache(t)
defer cache.Close()
assertCachedNode(t, cache, 10002)
assertHstore(t, []checkElem{
{"osm_all", 10002, "*", map[string]string{"random": "tag", "but": "mapped", "poi": "unicorn"}},
})
}
func TestSingleTable_NonMappedWayIsMissing(t *testing.T) {
// Way without mapped tags is missing.
cache := ts.cache(t)
defer cache.Close()
assertCachedWay(t, cache, 20101)
assertCachedWay(t, cache, 20102)
assertCachedWay(t, cache, 20103)
assertHstore(t, []checkElem{
{"osm_all", 20101, Missing, nil},
{"osm_all", 20102, Missing, nil},
{"osm_all", 20103, Missing, nil},
})
}
func TestSingleTable_MappedWay(t *testing.T) {
// Way is stored with all tags.
cache := ts.cache(t)
defer cache.Close()
assertCachedWay(t, cache, 20201)
assertHstore(t, []checkElem{
{"osm_all", -20201, "*", map[string]string{"random": "tag", "highway": "yes"}},
})
}
func TestSingleTable_NonMappedClosedWayIsMissing(t *testing.T) {
// Closed way without mapped tags is missing.
cache := ts.cache(t)
defer cache.Close()
assertCachedWay(t, cache, 20301)
assertHstore(t, []checkElem{
{"osm_all", 20301, Missing, nil},
{"osm_all", -20301, Missing, nil},
})
}
func TestSingleTable_MappedClosedWay(t *testing.T) {
// Closed way is stored with all tags.
assertHstore(t, []checkElem{
{"osm_all", -20401, "*", map[string]string{"random": "tag", "building": "yes"}},
})
}
func TestSingleTable_MappedClosedWayAreaYes(t *testing.T) {
// Closed way with area=yes is not stored as linestring.
assertHstore(t, []checkElem{
{"osm_all", -20501, "*", map[string]string{"random": "tag", "landuse": "grass", "highway": "pedestrian", "area": "yes"}},
})
assertGeomType(t, checkElem{"osm_all", -20501, "*", nil}, "Polygon")
}
func TestSingleTable_MappedClosedWayAreaNo(t *testing.T) {
// Closed way with area=no is not stored as polygon.
assertHstore(t, []checkElem{
{"osm_all", -20502, "*", map[string]string{"random": "tag", "landuse": "grass", "highway": "pedestrian", "area": "no"}},
})
assertGeomType(t, checkElem{"osm_all", -20502, "*", nil}, "LineString")
}
func TestSingleTable_MappedClosedWayWithoutArea(t *testing.T) {
// Closed way without area is stored as mapped (linestring and polygon).
rows := ts.queryRowsTags(t, "osm_all", -20601)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
}
}
func TestSingleTable_DuplicateIds1(t *testing.T) {
// Points/lines/polygons with same ID are inserted.
assertHstore(t, []checkElem{
{"osm_all", 31101, "*", map[string]string{"amenity": "cafe"}},
})
rows := ts.queryRowsTags(t, "osm_all", -31101)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
} }
assertHstore(t, []checkElem{ ts := importTestSuite{
{"osm_all", RelOffset - 31101, "*", map[string]string{"building": "yes", "type": "multipolygon"}}, name: "single_table",
})
assertGeomType(t, checkElem{"osm_all", RelOffset - 31101, "*", nil}, "Polygon")
}
// #######################################################################
func TestSingleTable_Update(t *testing.T) {
ts.updateOsm(t, "./build/single_table.osc.gz")
}
// #######################################################################
func TestSingleTable_DuplicateIds2(t *testing.T) {
// Node moved and ways/rels with same ID are still present.
assertHstore(t, []checkElem{
{"osm_all", 31101, "*", map[string]string{"amenity": "cafe"}},
})
rows := ts.queryRowsTags(t, "osm_all", -31101)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
} }
assertHstore(t, []checkElem{ t.Run("Prepare", func(t *testing.T) {
{"osm_all", RelOffset - 31101, "*", map[string]string{"building": "yes", "type": "multipolygon"}}, var err error
ts.dir, err = ioutil.TempDir("", "imposm_test")
if err != nil {
t.Fatal(err)
}
ts.config = importConfig{
connection: "postgis://",
cacheDir: ts.dir,
osmFileName: "build/single_table.pbf",
mappingFileName: "single_table_mapping.json",
}
ts.g = geos.NewGeos()
ts.db, err = sql.Open("postgres", "sslmode=disable")
if err != nil {
t.Fatal(err)
}
ts.dropSchemas()
}) })
assertGeomType(t, checkElem{"osm_all", RelOffset - 31101, "*", nil}, "Polygon")
}
func TestSingleTable_ModifiedRelation2(t *testing.T) { t.Run("Import", func(t *testing.T) {
// Modified relation is not inserted twice. Check for #88 if ts.tableExists(t, ts.dbschemaImport(), "osm_all") != false {
t.Fatalf("table osm_all exists in schema %s", ts.dbschemaImport())
}
ts.importOsm(t)
if ts.tableExists(t, ts.dbschemaImport(), "osm_all") != true {
t.Fatalf("table osm_all does not exists in schema %s", ts.dbschemaImport())
}
})
rows := ts.queryRowsTags(t, "osm_all", RelOffset-32901) t.Run("Deploy", func(t *testing.T) {
if len(rows) != 1 { ts.deployOsm(t)
t.Errorf("found duplicate row: %v", rows) if ts.tableExists(t, ts.dbschemaImport(), "osm_all") != false {
} t.Fatalf("table osm_all exists in schema %s", ts.dbschemaImport())
} }
if ts.tableExists(t, ts.dbschemaProduction(), "osm_all") != true {
t.Fatalf("table osm_all does not exists in schema %s", ts.dbschemaProduction())
}
})
func TestSingleTable_Cleanup(t *testing.T) { t.Run("NonMappedNodeIsMissing", func(t *testing.T) {
ts.dropSchemas() // Node without mapped tags is missing.
if err := os.RemoveAll(ts.dir); err != nil { cache := ts.cache(t)
t.Error(err) defer cache.Close()
} ts.assertCachedNode(t, cache, 10001)
ts.assertHstore(t, []checkElem{
{"osm_all", 10001, Missing, nil},
})
})
t.Run("MappedNode", func(t *testing.T) {
// Node is stored with all tags.
cache := ts.cache(t)
defer cache.Close()
ts.assertCachedNode(t, cache, 10002)
ts.assertHstore(t, []checkElem{
{"osm_all", 10002, "*", map[string]string{"random": "tag", "but": "mapped", "poi": "unicorn"}},
})
})
t.Run("NonMappedWayIsMissing", func(t *testing.T) {
// Way without mapped tags is missing.
cache := ts.cache(t)
defer cache.Close()
ts.assertCachedWay(t, cache, 20101)
ts.assertCachedWay(t, cache, 20102)
ts.assertCachedWay(t, cache, 20103)
ts.assertHstore(t, []checkElem{
{"osm_all", 20101, Missing, nil},
{"osm_all", 20102, Missing, nil},
{"osm_all", 20103, Missing, nil},
})
})
t.Run("MappedWay", func(t *testing.T) {
// Way is stored with all tags.
cache := ts.cache(t)
defer cache.Close()
ts.assertCachedWay(t, cache, 20201)
ts.assertHstore(t, []checkElem{
{"osm_all", -20201, "*", map[string]string{"random": "tag", "highway": "yes"}},
})
})
t.Run("NonMappedClosedWayIsMissing", func(t *testing.T) {
// Closed way without mapped tags is missing.
cache := ts.cache(t)
defer cache.Close()
ts.assertCachedWay(t, cache, 20301)
ts.assertHstore(t, []checkElem{
{"osm_all", 20301, Missing, nil},
{"osm_all", -20301, Missing, nil},
})
})
t.Run("MappedClosedWay", func(t *testing.T) {
// Closed way is stored with all tags.
ts.assertHstore(t, []checkElem{
{"osm_all", -20401, "*", map[string]string{"random": "tag", "building": "yes"}},
})
})
t.Run("MappedClosedWayAreaYes", func(t *testing.T) {
// Closed way with area=yes is not stored as linestring.
ts.assertHstore(t, []checkElem{
{"osm_all", -20501, "*", map[string]string{"random": "tag", "landuse": "grass", "highway": "pedestrian", "area": "yes"}},
})
ts.assertGeomType(t, checkElem{"osm_all", -20501, "*", nil}, "Polygon")
})
t.Run("MappedClosedWayAreaNo", func(t *testing.T) {
// Closed way with area=no is not stored as polygon.
ts.assertHstore(t, []checkElem{
{"osm_all", -20502, "*", map[string]string{"random": "tag", "landuse": "grass", "highway": "pedestrian", "area": "no"}},
})
ts.assertGeomType(t, checkElem{"osm_all", -20502, "*", nil}, "LineString")
})
t.Run("MappedClosedWayWithoutArea", func(t *testing.T) {
// Closed way without area is stored as mapped (linestring and polygon).
rows := ts.queryRowsTags(t, "osm_all", -20601)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
}
})
t.Run("DuplicateIds1", func(t *testing.T) {
// Points/lines/polygons with same ID are inserted.
ts.assertHstore(t, []checkElem{
{"osm_all", 31101, "*", map[string]string{"amenity": "cafe"}},
})
rows := ts.queryRowsTags(t, "osm_all", -31101)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
}
ts.assertHstore(t, []checkElem{
{"osm_all", RelOffset - 31101, "*", map[string]string{"building": "yes", "type": "multipolygon"}},
})
ts.assertGeomType(t, checkElem{"osm_all", RelOffset - 31101, "*", nil}, "Polygon")
})
// #######################################################################
t.Run("Update", func(t *testing.T) {
ts.updateOsm(t, "build/single_table.osc.gz")
})
// #######################################################################
t.Run("DuplicateIds2", func(t *testing.T) {
// Node moved and ways/rels with same ID are still present.
ts.assertHstore(t, []checkElem{
{"osm_all", 31101, "*", map[string]string{"amenity": "cafe"}},
})
rows := ts.queryRowsTags(t, "osm_all", -31101)
if len(rows) != 2 || strings.HasPrefix(rows[0].wkt, "LineString") || strings.HasPrefix(rows[1].wkt, "Polygon") {
t.Errorf("unexpected geometries: %v", rows)
}
ts.assertHstore(t, []checkElem{
{"osm_all", RelOffset - 31101, "*", map[string]string{"building": "yes", "type": "multipolygon"}},
})
ts.assertGeomType(t, checkElem{"osm_all", RelOffset - 31101, "*", nil}, "Polygon")
})
t.Run("ModifiedRelation2", func(t *testing.T) {
// Modified relation is not inserted twice. Check for #88
rows := ts.queryRowsTags(t, "osm_all", RelOffset-32901)
if len(rows) != 1 {
t.Errorf("found duplicate row: %v", rows)
}
})
t.Run("Cleanup", func(t *testing.T) {
ts.dropSchemas()
if err := os.RemoveAll(ts.dir); err != nil {
t.Error(err)
}
})
} }