]> git.openstreetmap.org Git - nominatim.git/commitdiff
Nominatim::DB tests against separate postgresql database
authormarc tobias <mtmail@gmx.net>
Mon, 13 Apr 2020 15:48:20 +0000 (17:48 +0200)
committermarc tobias <mtmail@gmx.net>
Mon, 13 Apr 2020 16:01:37 +0000 (18:01 +0200)
.travis.yml
lib/DB.php
lib/setup/SetupClass.php
test/README.md
test/php/Nominatim/DBTest.php
utils/check_import_finished.php

index f53447422c303ed9740a02edbd18a41acbd768e6..dd973aecbc2649f7ae1e86b29a41be32f121e59b 100644 (file)
@@ -25,7 +25,7 @@ script:
   - cd $TRAVIS_BUILD_DIR/
   - if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi
   - cd $TRAVIS_BUILD_DIR/test/php
   - cd $TRAVIS_BUILD_DIR/
   - if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi
   - cd $TRAVIS_BUILD_DIR/test/php
-  - if [[ $TEST_SUITE == "tests" ]]; then /usr/bin/phpunit ./ ; fi
+  - if [[ $TEST_SUITE == "tests" ]]; then UNIT_TEST_DSN='pgsql:dbname=nominatim_unit_tests' /usr/bin/phpunit ./ ; fi
   - cd $TRAVIS_BUILD_DIR/test/bdd
   - # behave --format=progress3 api
   - if [[ $TEST_SUITE == "tests" ]]; then behave -DREMOVE_TEMPLATE=1 --format=progress3 db ; fi
   - cd $TRAVIS_BUILD_DIR/test/bdd
   - # behave --format=progress3 api
   - if [[ $TEST_SUITE == "tests" ]]; then behave -DREMOVE_TEMPLATE=1 --format=progress3 db ; fi
index 6307d6ca2847bdf2a9d90354c33d79983c4c8077..5915b2e81242a727c82b9118c7ba0892114fb399 100644 (file)
@@ -240,6 +240,28 @@ class DB
         return ($this->getOne($sSQL, array(':tablename' => $sTableName)) == 1);
     }
 
         return ($this->getOne($sSQL, array(':tablename' => $sTableName)) == 1);
     }
 
+    /**
+    * Returns a list of table names in the database
+    *
+    * @return array[]
+    */
+    public function getListOfTables()
+    {
+        return $this->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'");
+    }
+
+    /**
+     * Deletes a table. Returns true on success. Returns true if the table didn't exist.
+     *
+     * @param string  $sTableName
+     *
+     * @return boolean
+     */
+    public function deleteTable($sTableName)
+    {
+        return $this->exec('DROP TABLE IF EXISTS '.$sTableName.' CASCADE') == 0;
+    }
+
     /**
     * Check if an index exists in the database. Optional filtered by tablename
     *
     /**
     * Check if an index exists in the database. Optional filtered by tablename
     *
@@ -311,11 +333,11 @@ END;
     }
 
     /**
     }
 
     /**
-     * Since the DSN includes the database name, checks if the connection works.
+     * Tries to connect to the database but on failure doesn't throw an exception.
      *
      * @return boolean
      */
      *
      * @return boolean
      */
-    public function databaseExists()
+    public function checkConnection()
     {
         $bExists = true;
         try {
     {
         $bExists = true;
         try {
@@ -350,6 +372,13 @@ END;
         return (float) ($aMatches[1].'.'.$aMatches[2]);
     }
 
         return (float) ($aMatches[1].'.'.$aMatches[2]);
     }
 
+    /**
+     * Returns an associate array of postgresql database connection settings. Keys can
+     * be 'database', 'hostspec', 'port', 'username', 'password'.
+     * Returns empty array on failure, thus check if at least 'database' is set.
+     *
+     * @return array[]
+     */
     public static function parseDSN($sDSN)
     {
         // https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
     public static function parseDSN($sDSN)
     {
         // https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
@@ -365,4 +394,41 @@ END;
         }
         return $aInfo;
     }
         }
         return $aInfo;
     }
+
+    /**
+     * Takes an array of settings and return the DNS string. Key names can be
+     * 'database', 'hostspec', 'port', 'username', 'password' but aliases
+     * 'dbname', 'host' and 'user' are also supported.
+     *
+     * @return string
+     *
+     */
+    public static function generateDSN($aInfo)
+    {
+        $sDSN = 'pgsql:';
+        if (isset($aInfo['host'])) {
+            $sDSN .= 'host=' . $aInfo['host'] . ';';
+        } elseif (isset($aInfo['hostspec'])) {
+            $sDSN .= 'host=' . $aInfo['hostspec'] . ';';
+        }
+        if (isset($aInfo['port'])) {
+            $sDSN .= 'port=' . $aInfo['port'] . ';';
+        }
+        if (isset($aInfo['dbname'])) {
+            $sDSN .= 'dbname=' . $aInfo['dbname'] . ';';
+        } elseif (isset($aInfo['database'])) {
+            $sDSN .= 'dbname=' . $aInfo['database'] . ';';
+        }
+        if (isset($aInfo['user'])) {
+            $sDSN .= 'user=' . $aInfo['user'] . ';';
+        } elseif (isset($aInfo['username'])) {
+            $sDSN .= 'user=' . $aInfo['username'] . ';';
+        }
+        if (isset($aInfo['password'])) {
+            $sDSN .= 'password=' . $aInfo['password'] . ';';
+        }
+        $sDSN = preg_replace('/;$/', '', $sDSN);
+
+        return $sDSN;
+    }
 }
 }
index ac0f8f02f89e33ccc6d0cae4a23c14fb042f98cb..7c1c628e0e70171b08a60d103b17cdaf152fdf60 100755 (executable)
@@ -84,7 +84,7 @@ class SetupFunctions
         info('Create DB');
         $oDB = new \Nominatim\DB;
 
         info('Create DB');
         $oDB = new \Nominatim\DB;
 
-        if ($oDB->databaseExists()) {
+        if ($oDB->checkConnection()) {
             fail('database already exists ('.CONST_Database_DSN.')');
         }
 
             fail('database already exists ('.CONST_Database_DSN.')');
         }
 
@@ -651,7 +651,7 @@ class SetupFunctions
                        );
 
         $aDropTables = array();
                        );
 
         $aDropTables = array();
-        $aHaveTables = $this->oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'");
+        $aHaveTables = $this->oDB->getListOfTables();
 
         foreach ($aHaveTables as $sTable) {
             $bFound = false;
 
         foreach ($aHaveTables as $sTable) {
             $bFound = false;
@@ -858,7 +858,7 @@ class SetupFunctions
     private function dropTable($sName)
     {
         if ($this->bVerbose) echo "Dropping table $sName\n";
     private function dropTable($sName)
     {
         if ($this->bVerbose) echo "Dropping table $sName\n";
-        $this->oDB->exec('DROP TABLE IF EXISTS '.$sName.' CASCADE');
+        $this->oDB->deleteTable($sName);
     }
 
     /**
     }
 
     /**
index ab5f7f4c653ef98cd65c454aa6dccfec43f2ce3e..5de08759532fb962cefb5d1afc87331d8576f777 100644 (file)
@@ -46,11 +46,13 @@ Very low coverage.
 To execute the test suite run
 
     cd test/php
 To execute the test suite run
 
     cd test/php
-    phpunit ../
+    UNIT_TEST_DSN='pgsql:dbname=nominatim_unit_tests' phpunit ../
 
 It will read phpunit.xml which points to the library, test path, bootstrap
 strip and set other parameters.
 
 
 It will read phpunit.xml which points to the library, test path, bootstrap
 strip and set other parameters.
 
+The database set by `UNIT_TEST_DSN` will be deleted and recreated. Not setting
+it will skip some tests as pending, but not fail the tests.
 
 BDD Functional Tests
 ====================
 
 BDD Functional Tests
 ====================
index 38874c880ec52cb2cc18f684ddf02a89ce8ab820..e47919758a449175683fa5721d3ab75d1ec7fa38 100644 (file)
@@ -24,10 +24,10 @@ class DBTest extends \PHPUnit\Framework\TestCase
         $this->assertTrue($oDB->connect());
     }
 
         $this->assertTrue($oDB->connect());
     }
 
-    public function testDatabaseExists()
+    public function testCheckConnection()
     {
         $oDB = new \Nominatim\DB('');
     {
         $oDB = new \Nominatim\DB('');
-        $this->assertFalse($oDB->databaseExists());
+        $this->assertFalse($oDB->checkConnection());
     }
 
     public function testErrorHandling()
     }
 
     public function testErrorHandling()
@@ -113,4 +113,126 @@ class DBTest extends \PHPUnit\Framework\TestCase
             \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret')
         );
     }
             \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret')
         );
     }
+
+    public function testGenerateDSN()
+    {
+        $this->assertEquals(
+            'pgsql:',
+            \Nominatim\DB::generateDSN(array())
+        );
+        $this->assertEquals(
+            'pgsql:host=machine1;dbname=db1',
+            \Nominatim\DB::generateDSN(\Nominatim\DB::parseDSN('pgsql:host=machine1;dbname=db1'))
+        );
+    }
+
+    public function testAgainstDatabase()
+    {
+        if (getenv('UNIT_TEST_DSN') == false) $this->markTestSkipped('UNIT_TEST_DSN not set');
+
+        ## Create the database.
+        {
+            $aDSNParsed = \Nominatim\DB::parseDSN(getenv('UNIT_TEST_DSN'));
+            $sDbname = $aDSNParsed['database'];
+            $aDSNParsed['database'] = 'postgres';
+
+            $oDB = new \Nominatim\DB(\Nominatim\DB::generateDSN($aDSNParsed));
+            $oDB->connect();
+            $oDB->exec('DROP DATABASE IF EXISTS ' . $sDbname);
+            $oDB->exec('CREATE DATABASE ' . $sDbname);
+        }
+
+        $oDB = new \Nominatim\DB(getenv('UNIT_TEST_DSN'));
+        $oDB->connect();
+
+        $this->assertTrue(
+            $oDB->checkConnection($sDbname)
+        );
+
+        # Tables, Indices
+        {
+            $this->assertEmpty($oDB->getListOfTables());
+            $oDB->exec('CREATE TABLE table1 (id integer, city varchar, country varchar)');
+            $oDB->exec('CREATE TABLE table2 (id integer, city varchar, country varchar)');
+            $this->assertEquals(
+                array('table1', 'table2'),
+                $oDB->getListOfTables()
+            );
+            $this->assertTrue($oDB->deleteTable('table2'));
+            $this->assertTrue($oDB->deleteTable('table99'));
+            $this->assertEquals(
+                array('table1'),
+                $oDB->getListOfTables()
+            );
+
+            $this->assertTrue($oDB->tableExists('table1'));
+            $this->assertFalse($oDB->tableExists('table99'));
+            $this->assertFalse($oDB->tableExists(null));
+
+            $this->assertEmpty($oDB->getListOfIndices());
+            $oDB->exec('CREATE UNIQUE INDEX table1_index ON table1 (id)');
+            $this->assertEquals(
+                array('table1_index'),
+                $oDB->getListOfIndices()
+            );
+            $this->assertEmpty($oDB->getListOfIndices('table2'));
+        }
+
+        # select queries
+        {
+            $oDB->exec(
+                "INSERT INTO table1 VALUES (1, 'Berlin', 'Germany'), (2, 'Paris', 'France')"
+            );
+
+            $this->assertEquals(
+                array(
+                    array('city' => 'Berlin'),
+                    array('city' => 'Paris')
+                ),
+                $oDB->getAll('SELECT city FROM table1')
+            );
+            $this->assertEquals(
+                array(),
+                $oDB->getAll('SELECT city FROM table1 WHERE id=999')
+            );
+
+
+            $this->assertEquals(
+                array('id' => 1, 'city' => 'Berlin', 'country' => 'Germany'),
+                $oDB->getRow('SELECT * FROM table1 WHERE id=1')
+            );
+            $this->assertEquals(
+                false,
+                $oDB->getRow('SELECT * FROM table1 WHERE id=999')
+            );
+
+
+            $this->assertEquals(
+                array('Berlin', 'Paris'),
+                $oDB->getCol('SELECT city FROM table1')
+            );
+            $this->assertEquals(
+                array(),
+                $oDB->getCol('SELECT city FROM table1 WHERE id=999')
+            );
+
+            $this->assertEquals(
+                'Berlin',
+                $oDB->getOne('SELECT city FROM table1 WHERE id=1')
+            );
+            $this->assertEquals(
+                null,
+                $oDB->getOne('SELECT city FROM table1 WHERE id=999')
+            );
+
+            $this->assertEquals(
+                array('Berlin' => 'Germany', 'Paris' => 'France'),
+                $oDB->getAssoc('SELECT city, country FROM table1')
+            );
+            $this->assertEquals(
+                array(),
+                $oDB->getAssoc('SELECT city, country FROM table1 WHERE id=999')
+            );
+        }
+    }
 }
 }
index b81cace1702d3af50392d7682d56c3f11fbbe9ba..4529c69394b53c8cab1e50775c549fe516d942c5 100755 (executable)
@@ -28,7 +28,7 @@ function isReverseOnlyInstallation()
 
 
 echo 'Checking database got created ... ';
 
 
 echo 'Checking database got created ... ';
-if ($oDB->databaseExists()) {
+if ($oDB->checkConnection()) {
     $print_success();
 } else {
     $print_fail();
     $print_success();
 } else {
     $print_fail();