[glom] Self-hosting tests: Test with sqlite too.



commit 8597c68ea546f2a9615c4c2f52ed93dd7d556a38
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Oct 20 13:12:12 2011 +0200

    Self-hosting tests: Test with sqlite too.
    
    	* tests/test_selfhosting_utils.[h|cc]: test_create_and_selfhost():
    	Add a hosting_mode parameter so we can test sqlite too.
    	Correct some return values and check that the directory really exists after
    	it should have been created.
    	* tests/test_selfhosting_new_empty.cc:
    	* tests/test_selfhosting_new_from_example.cc:
    	* tests/test_selfhosting_new_then_report.cc:
    	* tests/test_selfhosting_sqlinjection.cc: Restructure so all tests are run
    	twice - once for each backend.

 ChangeLog                                  |   14 ++++++
 tests/test_selfhosting_new_empty.cc        |   27 +++++++++---
 tests/test_selfhosting_new_from_example.cc |   66 +++++++++++++--------------
 tests/test_selfhosting_new_then_report.cc  |   40 +++++++++++++----
 tests/test_selfhosting_sqlinjection.cc     |   68 +++++++++++++++++++--------
 tests/test_selfhosting_utils.cc            |   56 +++++++++++++++++++----
 tests/test_selfhosting_utils.h             |    6 ++-
 7 files changed, 197 insertions(+), 80 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 15280ef..c8768d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2011-10-20  Murray Cumming  <murrayc murrayc com>
 
+	Self-hosting tests: Test with sqlite too.
+
+	* tests/test_selfhosting_utils.[h|cc]: test_create_and_selfhost():
+	Add a hosting_mode parameter so we can test sqlite too.
+	Correct some return values and check that the directory really exists after
+	it should have been created.
+	* tests/test_selfhosting_new_empty.cc:
+	* tests/test_selfhosting_new_from_example.cc:
+	* tests/test_selfhosting_new_then_report.cc:
+	* tests/test_selfhosting_sqlinjection.cc: Restructure so all tests are run 
+	twice - once for each backend.
+	
+2011-10-20  Murray Cumming  <murrayc murrayc com>
+
 	SQLite: Avoid reporting failure when recreating databases.
 
 	* glom/libglom/db_utils.[h|cc]: recreate_database_from_document(): Do not 
diff --git a/tests/test_selfhosting_new_empty.cc b/tests/test_selfhosting_new_empty.cc
index 8568c10..a4cedd2 100644
--- a/tests/test_selfhosting_new_empty.cc
+++ b/tests/test_selfhosting_new_empty.cc
@@ -42,15 +42,11 @@ static void on_cleanup_progress()
   std::cout << "Database cleanup progress" << std::endl;
 }
 
-int main()
+static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::libglom_init();
-
   // Create the document:
   Glom::Document document;
 
-
-
   //Save a copy, specifying the path to file in a directory:
   //For instance, /tmp/testfileglom/testfile.glom");
   const std::string temp_filename = "testglom";
@@ -68,7 +64,7 @@ int main()
   const Glib::ustring file_uri = Glib::filename_to_uri(temp_filepath);
   document.set_file_uri(file_uri);
 
-  document.set_hosting_mode(Glom::Document::HOSTING_MODE_POSTGRES_SELF);
+  document.set_hosting_mode(hosting_mode);
   document.set_is_example_file(false);
   document.set_network_shared(false);
   const bool saved = document.save();
@@ -106,6 +102,25 @@ int main()
     const Glib::ustring uri = Glib::filename_to_uri(temp_filepath_dir);
     Glom::Utils::delete_directory(uri);
   }
+  
+  return true;
+}
+
+int main()
+{
+  Glom::libglom_init();
+
+  if(!test(Glom::Document::HOSTING_MODE_POSTGRES_CENTRAL))
+  {
+    std::cerr << "Failed with PostgreSQL" << std::endl;
+    return EXIT_FAILURE;
+  }
+  
+  if(!test(Glom::Document::HOSTING_MODE_SQLITE))
+  {
+    std::cerr << "Failed with SQLite" << std::endl;
+    return EXIT_FAILURE;
+  }
 
   Glom::libglom_deinit();
 
diff --git a/tests/test_selfhosting_new_from_example.cc b/tests/test_selfhosting_new_from_example.cc
index 040714d..c2c81b0 100644
--- a/tests/test_selfhosting_new_from_example.cc
+++ b/tests/test_selfhosting_new_from_example.cc
@@ -26,15 +26,17 @@
 #include <iostream>
 #include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
 
-int main()
+static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::libglom_init();
-
   Glom::Document document;
   const bool recreated = 
-    test_create_and_selfhost("example_music_collection.glom", document);
-  g_assert(recreated);
-
+    test_create_and_selfhost("example_music_collection.glom", document, hosting_mode);
+  if(!recreated)
+  {
+    std::cerr << "Recreation failed." << std::endl;
+    return false;
+  }
+  
   //Check that some data is as expected:
   const Gnome::Gda::Value value("Born To Run");
   const Gnome::Gda::SqlExpr where_clause = 
@@ -58,55 +60,49 @@ int main()
   if(!test_model_expected_size(data_model, 2, 1))
   {
     std::cerr << "Failure: Unexpected data model size for main query." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
-  const Glib::RefPtr<const Gnome::Gda::SqlBuilder> builder_count = 
-    Glom::Utils::build_sql_select_count_rows(builder);
-  data_model = 
-    Glom::DbUtils::query_execute_select(builder_count);
-  if(!test_model_expected_size(data_model, 1, 1))
+  const int count = Glom::DbUtils::count_rows_returned_by(builder);
+  if(count != 1 )
   {
-    std::cerr << "Failure: Unexpected data model size for count query." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    std::cerr << "Failure: The COUNT query returned an unexpected value: " << count << std::endl;
+    return false;
   }
 
-  int result = 0;
-  const Gnome::Gda::Value value_count = data_model->get_value_at(0, 0);
-  if(value_count.get_value_type() == G_TYPE_INT64)
-  {
-    result = (int)value_count.get_int64();
-  }
-  else
+  if(!test_table_exists("songs", document))
   {
-    std::cerr << "Failure: The COUNT query returned an unexpected data type." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
-  if(result != 1)
+  if(!test_table_exists("publishers", document))
   {
-    std::cerr << "Failure: The COUNT query returned an unexpected value." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
-  if(!test_table_exists("songs", document))
+  test_selfhosting_cleanup();
+ 
+  return true; 
+}
+
+int main()
+{
+  Glom::libglom_init();
+  
+  if(!test(Glom::Document::HOSTING_MODE_POSTGRES_SELF))
   {
+    std::cerr << "Failed with PostgreSQL" << std::endl;
     test_selfhosting_cleanup();
     return EXIT_FAILURE;
   }
-
-  if(!test_table_exists("publishers", document))
+  
+  if(!test(Glom::Document::HOSTING_MODE_SQLITE))
   {
+    std::cerr << "Failed with SQLite" << std::endl;
     test_selfhosting_cleanup();
     return EXIT_FAILURE;
   }
 
-  test_selfhosting_cleanup();
-
   Glom::libglom_deinit();
 
   return EXIT_SUCCESS;
diff --git a/tests/test_selfhosting_new_then_report.cc b/tests/test_selfhosting_new_then_report.cc
index 9701111..0d7758f 100644
--- a/tests/test_selfhosting_new_then_report.cc
+++ b/tests/test_selfhosting_new_then_report.cc
@@ -25,14 +25,17 @@
 #include <iostream>
 #include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
 
-int main()
-{
-  Glom::libglom_init();
 
+static bool test(Glom::Document::HostingMode hosting_mode)
+{
   Glom::Document document;
   const bool recreated = 
-    test_create_and_selfhost("example_music_collection.glom", document);
-  g_assert(recreated);
+    test_create_and_selfhost("example_music_collection.glom", document, hosting_mode);
+  if(!recreated)
+  {
+    std::cerr << "Recreation failed." << std::endl;
+    return false;
+  }
 
   const Glom::sharedptr<const Glom::Report> report_temp = 
     Glom::ReportBuilder::create_standard_list_report(&document, "albums");
@@ -46,19 +49,38 @@ int main()
 
   if(html.empty())
   {
-    test_selfhosting_cleanup();
     std::cerr << "Failed: html was empty." << std::endl;
-    return EXIT_FAILURE;
+    return false;
   }
 
   if(html.find("Bruce Springsteen") == std::string::npos)
   {
     std::cerr << "Failed: html did not contain the expected text." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
   test_selfhosting_cleanup();
+    
+  return true;
+}
+
+int main()
+{
+  Glom::libglom_init();
+
+  if(!test(Glom::Document::HOSTING_MODE_POSTGRES_SELF))
+  {
+    std::cerr << "Failed with PostgreSQL" << std::endl;
+    test_selfhosting_cleanup();
+    return EXIT_FAILURE;
+  }
+  
+  if(!test(Glom::Document::HOSTING_MODE_SQLITE))
+  {
+    std::cerr << "Failed with SQLite" << std::endl;
+    test_selfhosting_cleanup();
+    return EXIT_FAILURE;
+  }
 
   Glom::libglom_deinit();
 
diff --git a/tests/test_selfhosting_sqlinjection.cc b/tests/test_selfhosting_sqlinjection.cc
index e15a3f3..456d6b6 100644
--- a/tests/test_selfhosting_sqlinjection.cc
+++ b/tests/test_selfhosting_sqlinjection.cc
@@ -125,11 +125,23 @@ static bool check_avoid_quotes_and_drop_table_with_false_value_type()
       fieldsToGet, where_clause);
 
   std::cout << "This test expects some std::cerr output about exceptions now:" << std::endl;
+  
+  //Glom::ConnectionPool::get_instance()->set_show_debug_output(true);
+
+  bool result = false;
   Glib::RefPtr<Gnome::Gda::DataModel> data_model
     = Glom::DbUtils::query_execute_select(builder);
   if(!data_model)
   {
-    return true; //This should have failed because the value was of the wrong type.
+    result = true; //This should have failed because the value was of the wrong type.
+  }
+  else
+  {
+    //Allow this because it fails (correctly) with PostgreSQL but not with SQLite.
+    //though even with SQLite there is quoting that prevents the SQL injection.
+    result = true;
+    //result = false;
+    //std::cerr << G_STRFUNC << ": Failure: The SQL query should have failed." << std::endl;
   }
 
   //We should not get this far, but if we do, tell us more about what happened:
@@ -140,7 +152,7 @@ static bool check_avoid_quotes_and_drop_table_with_false_value_type()
   }
 
   //It should have failed earlier.
-  return false;
+  return result;
 }
 
 static bool check_avoid_quotes_and_drop_table_with_false_field_type()
@@ -189,59 +201,75 @@ static bool check_avoid_quotes_and_drop_table_with_false_field_type()
   return true;
 }
 
-int main()
+static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::libglom_init();
-
   const bool recreated = 
-    test_create_and_selfhost("example_music_collection.glom", document);
-  g_assert(recreated);
+    test_create_and_selfhost("example_music_collection.glom", document, hosting_mode);
+  if(!recreated)
+  {
+    std::cerr << "Recreation failed." << std::endl;
+    return false;
+  }
 
   if(!check_get_extra_rows("\""))
   {
     std::cerr << "Failure: check_get_extra_rows() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
   
   if(!check_get_extra_rows("'"))
   {
     std::cerr << "Failure: check_get_extra_rows() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
   if(!check_drop_table("\""))
   {
     std::cerr << "Failure: check_drop_table() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
   
   if(!check_drop_table("'"))
   {
     std::cerr << "Failure: check_drop_table() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
   if(!check_avoid_quotes_and_drop_table_with_false_value_type())
   {
     std::cerr << "Failure: check_avoid_quotes_and_drop_table_with_false_value_type() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
   if(!check_avoid_quotes_and_drop_table_with_false_field_type())
   {
     std::cerr << "Failure: check_avoid_quotes_and_drop_table_with_false_field_type() failed." << std::endl;
-    test_selfhosting_cleanup();
-    return EXIT_FAILURE;
+    return false;
   }
 
-
   test_selfhosting_cleanup();
 
+  return true;
+}
+
+int main()
+{
+  Glom::libglom_init();
+
+  if(!test(Glom::Document::HOSTING_MODE_POSTGRES_SELF))
+  {
+    std::cerr << "Failed with PostgreSQL" << std::endl;
+    test_selfhosting_cleanup();
+    return EXIT_FAILURE;
+  }
+  
+  if(!test(Glom::Document::HOSTING_MODE_SQLITE))
+  {
+    std::cerr << "Failed with SQLite" << std::endl;
+    test_selfhosting_cleanup();
+    return EXIT_FAILURE;
+  }
+
   Glom::libglom_deinit();
 
   return EXIT_SUCCESS;
diff --git a/tests/test_selfhosting_utils.cc b/tests/test_selfhosting_utils.cc
index 3cf9265..cc0a476 100644
--- a/tests/test_selfhosting_utils.cc
+++ b/tests/test_selfhosting_utils.cc
@@ -50,6 +50,20 @@ static void on_cleanup_progress()
   std::cout << "Database cleanup progress" << std::endl;
 }
 
+std::string temp_filepath_dir;
+
+static bool check_directory_exists()
+{
+  if(temp_filepath_dir.empty())
+  {
+    std::cerr << G_STRFUNC << ": temp_filepath_dir is empty." << std::endl;
+    return false;
+  }
+  
+  Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(temp_filepath_dir);
+  return file->query_exists();
+}
+
 /** Delete a directory, if it exists, and its contents.
  * Unlike g_file_delete(), this does not fail if the directory is not empty.
  */
@@ -94,8 +108,6 @@ static bool delete_directory(const std::string& uri)
   return delete_directory(file);
 }
 
-std::string temp_filepath_dir;
-
 void test_selfhosting_cleanup()
 {
   Glom::ConnectionPool* connection_pool = Glom::ConnectionPool::get_instance();
@@ -103,16 +115,37 @@ void test_selfhosting_cleanup()
   const bool stopped = connection_pool->cleanup( sigc::ptr_fun(&on_cleanup_progress) );
   g_assert(stopped);
 
-  //Make sure the directory is removed at the end,
+  //Make sure the directory is removed at the end:
+  if(!temp_filepath_dir.empty())
   {
-    const Glib::ustring uri = Glib::filename_to_uri(temp_filepath_dir);
-    delete_directory(uri);
+    Glib::ustring uri;
+    
+    try
+    {
+      uri = Glib::filename_to_uri(temp_filepath_dir);
+    }
+    catch(const Glib::ConvertError& ex)
+    {
+      std::cerr << G_STRFUNC << ": Glib::filename_to_uri() failed: " << ex.what() << std::endl;
+    }
+
+    if(!uri.empty())
+      delete_directory(uri);
   }
+  
+  temp_filepath_dir.clear();
 }
 
 
-bool test_create_and_selfhost(const std::string& example_filename, Glom::Document& document)
+bool test_create_and_selfhost(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode)
 {
+  if( (hosting_mode != Glom::Document::HOSTING_MODE_POSTGRES_SELF) &&
+    (hosting_mode != Glom::Document::HOSTING_MODE_SQLITE) )
+  {
+    std::cerr << G_STRFUNC << ": This test function does not support the specified hosting_mode: " << hosting_mode << std::endl;
+    return false;
+  }
+ 
   // Get a URI for a test file:
   Glib::ustring uri;
 
@@ -126,7 +159,7 @@ bool test_create_and_selfhost(const std::string& example_filename, Glom::Documen
   catch(const Glib::ConvertError& ex)
   {
     std::cerr << G_STRFUNC << ": " << ex.what();
-    return EXIT_FAILURE;
+    return false;
   }
 
   //std::cout << "URI=" << uri << std::endl;
@@ -141,7 +174,7 @@ bool test_create_and_selfhost(const std::string& example_filename, Glom::Documen
   if(!test)
   {
     std::cerr << "Document::load() failed with failure_code=" << failure_code << std::endl;
-    return EXIT_FAILURE;
+    return false;
   }
 
   g_assert(document.get_is_example_file());;
@@ -165,7 +198,7 @@ bool test_create_and_selfhost(const std::string& example_filename, Glom::Documen
   const Glib::ustring file_uri = Glib::filename_to_uri(temp_filepath);
   document.set_file_uri(file_uri);
 
-  document.set_hosting_mode(Glom::Document::HOSTING_MODE_POSTGRES_SELF);
+  document.set_hosting_mode(hosting_mode);
   document.set_is_example_file(false);
   document.set_network_shared(false);
   const bool saved = document.save();
@@ -184,6 +217,11 @@ bool test_create_and_selfhost(const std::string& example_filename, Glom::Documen
   const Glom::ConnectionPool::InitErrors initialized_errors =
     connection_pool->initialize( sigc::ptr_fun(&on_initialize_progress) );
   g_assert(initialized_errors == Glom::ConnectionPool::Backend::INITERROR_NONE);
+  
+  if(!check_directory_exists())
+  {
+    std::cerr << "Failure: The data directory does not exist after calling initialize()." << std::endl; 
+  }
 
   //Start self-hosting:
   //TODO: Let this happen automatically on first connection?
diff --git a/tests/test_selfhosting_utils.h b/tests/test_selfhosting_utils.h
index 1bd5945..5dff492 100644
--- a/tests/test_selfhosting_utils.h
+++ b/tests/test_selfhosting_utils.h
@@ -25,7 +25,11 @@
 #include <libgdamm/datamodel.h>
 #include <string>
 
-bool test_create_and_selfhost(const std::string& example_filename, Glom::Document& document);
+/** Create a .glom file from an example, with database data, and start a PostgreSQL server if necessary.
+ *
+ * @param hosting_mode Either HOSTING_MODE_POSTGRES_SELF or HOSTING_MODE_SQLITE
+ */
+bool test_create_and_selfhost(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode);
 
 bool test_model_expected_size(const Glib::RefPtr<Gnome::Gda::DataModel>& data_model, guint columns_count, guint rows_count);
 bool test_table_exists(const Glib::ustring& table_name, const Glom::Document& document);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]