Browse Source

Implement ctest_upload command

Zach Mullen 15 years ago
parent
commit
350546db3a

+ 2 - 0
Source/CMakeLists.txt

@@ -394,6 +394,8 @@ SET(CTEST_SRCS cmCTest.cxx
   CTest/cmCTestTestHandler.cxx
   CTest/cmCTestUpdateCommand.cxx
   CTest/cmCTestUpdateHandler.cxx
+  CTest/cmCTestUploadCommand.cxx
+  CTest/cmCTestUploadHandler.cxx
 
   CTest/cmCTestVC.cxx
   CTest/cmCTestVC.h

+ 2 - 0
Source/CTest/cmCTestScriptHandler.cxx

@@ -50,6 +50,7 @@
 #include "cmCTestSubmitCommand.h"
 #include "cmCTestTestCommand.h"
 #include "cmCTestUpdateCommand.h"
+#include "cmCTestUploadCommand.h"
 
 #define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
 
@@ -357,6 +358,7 @@ void cmCTestScriptHandler::CreateCMake()
   this->AddCTestCommand(new cmCTestSubmitCommand);
   this->AddCTestCommand(new cmCTestTestCommand);
   this->AddCTestCommand(new cmCTestUpdateCommand);
+  this->AddCTestCommand(new cmCTestUploadCommand);
 }
 
 void cmCTestScriptHandler::GetCommandDocumentation(

+ 1 - 0
Source/CTest/cmCTestSubmitHandler.cxx

@@ -1204,6 +1204,7 @@ int cmCTestSubmitHandler::ProcessHandler()
   this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis.xml");
   this->CTest->AddIfExists(cmCTest::PartMemCheck, "Purify.xml");
   this->CTest->AddIfExists(cmCTest::PartNotes, "Notes.xml");
+  this->CTest->AddIfExists(cmCTest::PartUpload, "Upload.xml");
 
   // Query parts for files to submit.
   for(cmCTest::Part p = cmCTest::PartStart;

+ 1 - 43
Source/CTest/cmCTestTestHandler.cxx

@@ -1282,7 +1282,7 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
       result->Properties->AttachedFiles.begin();
       file != result->Properties->AttachedFiles.end(); ++file)
     {
-    std::string base64 = this->EncodeFile(*file);
+    std::string base64 = this->CTest->Base64GzipEncodeFile(*file);
     std::string fname = cmSystemTools::GetFilenameName(*file);
     os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" "
       "compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">"
@@ -1292,48 +1292,6 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
     }
 }
 
-//----------------------------------------------------------------------
-std::string cmCTestTestHandler::EncodeFile(std::string file)
-{
-  std::string tarFile = file + "_temp.tar.gz";
-  std::vector<cmStdString> files;
-  files.push_back(file);
-
-  if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false))
-    {
-    cmCTestLog(this->CTest, ERROR_MESSAGE, "Error creating tar while "
-      "attaching file: " << file << std::endl);
-    return "";
-    }
-  long len = cmSystemTools::FileLength(tarFile.c_str());
-  std::ifstream ifs(tarFile.c_str(), std::ios::in
-#ifdef _WIN32
-    | std::ios::binary
-#endif
-    );
-  unsigned char *file_buffer = new unsigned char [ len + 1 ];
-  ifs.read(reinterpret_cast<char*>(file_buffer), len);
-  ifs.close();
-  cmSystemTools::RemoveFile(tarFile.c_str());
-
-  unsigned char *encoded_buffer
-    = new unsigned char [ static_cast<int>(
-        static_cast<double>(len) * 1.5 + 5.0) ];
-
-  unsigned long rlen
-    = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
-
-  std::string base64 = "";
-  for(unsigned long i = 0; i < rlen; i++)
-    {
-    base64 += encoded_buffer[i];
-    }
-  delete [] file_buffer;
-  delete [] encoded_buffer;
-
-  return base64;
-}
-
 //----------------------------------------------------------------------
 int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
 {

+ 0 - 2
Source/CTest/cmCTestTestHandler.h

@@ -151,8 +151,6 @@ protected:
   void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
   // Write attached test files into the xml
   void AttachFiles(std::ostream& os, cmCTestTestResult* result);
-  // Helper function to encode attached test files
-  std::string EncodeFile(std::string file);
 
   //! Clean test output to specified length
   bool CleanTestOutput(std::string& output, size_t length);

+ 57 - 0
Source/CTest/cmCTestUploadCommand.cxx

@@ -0,0 +1,57 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCTestUploadCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+#include "cmCTestUploadHandler.h"
+
+cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+{
+  cmCTestGenericHandler* handler
+    = this->CTest->GetInitializedHandler("upload");
+  if ( !handler )
+    {
+    this->SetError("internal CTest error. Cannot instantiate upload handler");
+    return 0;
+    }
+  static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files);
+
+  return handler;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
+{
+  return this->CheckArgumentValue(arg);
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
+{
+  cmStdString filename(arg);
+  if(cmSystemTools::FileExists(filename.c_str()))
+    {
+    this->Files.insert(filename);
+    return true;
+    }
+  else
+    {
+    cmOStringStream e;
+    e << "File \"" << filename << "\" does not exist. Cannot submit "
+        << "a non-existent file.";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return false;
+    }
+}

+ 79 - 0
Source/CTest/cmCTestUploadCommand.h

@@ -0,0 +1,79 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmCTestUploadCommand_h
+#define cmCTestUploadCommand_h
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCTest.h"
+
+/** \class cmCTestUpload
+ * \brief Run a ctest script
+ *
+ * cmCTestUploadCommand defines the command to upload result files for
+ * the project.
+ */
+class cmCTestUploadCommand : public cmCTestHandlerCommand
+{
+public:
+
+  cmCTestUploadCommand()
+    {
+    }
+
+  /**
+   * This is a virtual constructor for the command.
+   */
+  virtual cmCommand* Clone()
+    {
+    cmCTestUploadCommand* ni = new cmCTestUploadCommand;
+    ni->CTest = this->CTest;
+    ni->CTestScriptHandler = this->CTestScriptHandler;
+    return ni;
+    }
+
+  /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual const char* GetName() { return "ctest_upload";}
+
+  /**
+   * Succinct documentation.
+   */
+  virtual const char* GetTerseDocumentation()
+    {
+    return "Upload files to a dashboard server.";
+    }
+
+  /**
+   * More documentation.
+   */
+  virtual const char* GetFullDocumentation()
+    {
+    return
+      "  ctest_upload(...)\n"
+      "Pass a list of files to be sent along with the build results to "
+      "the dashboard server.\n";
+    }
+
+  cmTypeMacro(cmCTestUploadCommand, cmCTestHandlerCommand);
+
+protected:
+  cmCTestGenericHandler* InitializeHandler();
+
+  virtual bool CheckArgumentKeyword(std::string const& arg);
+  virtual bool CheckArgumentValue(std::string const& arg);
+
+  cmCTest::SetOfStrings Files;
+};
+
+
+#endif

+ 77 - 0
Source/CTest/cmCTestUploadHandler.cxx

@@ -0,0 +1,77 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc.
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCTestUploadHandler.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmVersion.h"
+#include "cmXMLSafe.h"
+
+//----------------------------------------------------------------------------
+cmCTestUploadHandler::cmCTestUploadHandler()
+{
+  this->Initialize();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestUploadHandler::Initialize()
+{
+  this->Superclass::Initialize();
+  this->Files.clear();
+}
+
+void cmCTestUploadHandler::SetFiles(const cmCTest::SetOfStrings& files)
+{
+  this->Files = files;
+}
+
+//----------------------------------------------------------------------------
+int cmCTestUploadHandler::ProcessHandler()
+{
+  cmGeneratedFileStream ofs;
+  if ( !this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(),
+                                    "Upload.xml", ofs))
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+      "Cannot open Upload.xml file" << std::endl);
+    return -1;
+    }
+
+  cmCTest::SetOfStrings::const_iterator it;
+  ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+     << "<?xml-stylesheet type=\"text/xsl\" "
+    "href=\"Dart/Source/Server/XSL/Build.xsl "
+    "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
+     << "<Site BuildName=\""
+     << this->CTest->GetCTestConfiguration("BuildName")
+     << "\" BuildStamp=\""
+     << this->CTest->GetCurrentTag() << "-"
+     << this->CTest->GetTestModelString() << "\" Name=\""
+     << this->CTest->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
+     << cmVersion::GetCMakeVersion()
+     << "\">\n";
+  this->CTest->AddSiteProperties(ofs);
+  ofs << "<Files>\n";
+
+  for ( it = this->Files.begin(); it != this->Files.end(); it ++ )
+    {
+    cmCTestLog(this->CTest, OUTPUT,
+               "\tUpload file: " << it->c_str() << std::endl);
+    ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n"
+       << "<Content compression=\"tar/gzip\" encoding=\"base64\">\n";
+    ofs << this->CTest->Base64GzipEncodeFile(*it);
+    ofs << "\n</Content>\n"
+      << "</File>\n";
+    }
+  ofs << "</Files>\n"
+    << "</Site>\n";
+  return 0;
+}

+ 45 - 0
Source/CTest/cmCTestUploadHandler.h

@@ -0,0 +1,45 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmCTestUploadHandler_h
+#define cmCTestUploadHandler_h
+
+#include "cmCTestGenericHandler.h"
+
+/** \class cmCTestUploadHandler
+ * \brief Helper class for CTest
+ *
+ * Submit arbitrary files
+ *
+ */
+class cmCTestUploadHandler : public cmCTestGenericHandler
+{
+public:
+  cmTypeMacro(cmCTestUploadHandler, cmCTestGenericHandler);
+
+  cmCTestUploadHandler();
+  ~cmCTestUploadHandler() {}
+
+  /*
+   * The main entry point for this class
+   */
+  int ProcessHandler();
+
+  void Initialize();
+
+  /** Specify a set of files to submit.  */
+  void SetFiles(cmCTest::SetOfStrings const& files);
+
+private:
+  cmCTest::SetOfStrings Files;
+};
+
+#endif

+ 47 - 1
Source/cmCTest.cxx

@@ -16,6 +16,7 @@
 #include "cmMakefile.h"
 #include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
+#include <cmsys/Base64.h>
 #include <cmsys/Directory.hxx>
 #include <cmsys/SystemInformation.hxx>
 #include "cmDynamicLoader.h"
@@ -31,9 +32,10 @@
 #include "cmCTestCoverageHandler.h"
 #include "cmCTestMemCheckHandler.h"
 #include "cmCTestScriptHandler.h"
+#include "cmCTestSubmitHandler.h"
 #include "cmCTestTestHandler.h"
 #include "cmCTestUpdateHandler.h"
-#include "cmCTestSubmitHandler.h"
+#include "cmCTestUploadHandler.h"
 
 #include "cmVersion.h"
 
@@ -339,6 +341,7 @@ cmCTest::cmCTest()
   this->Parts[PartSubmit].SetName("Submit");
   this->Parts[PartNotes].SetName("Notes");
   this->Parts[PartExtraFiles].SetName("ExtraFiles");
+  this->Parts[PartUpload].SetName("Upload");
 
   // Fill the part name-to-id map.
   for(Part p = PartStart; p != PartCount; p = Part(p+1))
@@ -357,6 +360,7 @@ cmCTest::cmCTest()
   this->TestingHandlers["configure"] = new cmCTestConfigureHandler;
   this->TestingHandlers["memcheck"]  = new cmCTestMemCheckHandler;
   this->TestingHandlers["submit"]    = new cmCTestSubmitHandler;
+  this->TestingHandlers["upload"]    = new cmCTestUploadHandler;
 
   cmCTest::t_TestingHandlers::iterator it;
   for ( it = this->TestingHandlers.begin();
@@ -1583,6 +1587,48 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
   return this->GenerateNotesFile(files);
 }
 
+//----------------------------------------------------------------------
+std::string cmCTest::Base64GzipEncodeFile(std::string file)
+{
+  std::string tarFile = file + "_temp.tar.gz";
+  std::vector<cmStdString> files;
+  files.push_back(file);
+
+  if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false))
+    {
+    cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while "
+      "encoding file: " << file << std::endl);
+    return "";
+    }
+  long len = cmSystemTools::FileLength(tarFile.c_str());
+  std::ifstream ifs(tarFile.c_str(), std::ios::in
+#ifdef _WIN32
+    | std::ios::binary
+#endif
+    );
+  unsigned char *file_buffer = new unsigned char [ len + 1 ];
+  ifs.read(reinterpret_cast<char*>(file_buffer), len);
+  ifs.close();
+  cmSystemTools::RemoveFile(tarFile.c_str());
+
+  unsigned char *encoded_buffer
+    = new unsigned char [ static_cast<int>(
+        static_cast<double>(len) * 1.5 + 5.0) ];
+
+  unsigned long rlen
+    = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+
+  std::string base64 = "";
+  for(unsigned long i = 0; i < rlen; i++)
+    {
+    base64 += encoded_buffer[i];
+    }
+  delete [] file_buffer;
+  delete [] encoded_buffer;
+
+  return base64;
+}
+
 //----------------------------------------------------------------------
 bool cmCTest::SubmitExtraFiles(const std::vector<cmStdString> &files)
 {

+ 6 - 2
Source/cmCTest.h

@@ -61,6 +61,7 @@ public:
     PartSubmit,
     PartNotes,
     PartExtraFiles,
+    PartUpload,
     PartCount // Update names in constructor when adding a part
   };
 
@@ -192,8 +193,11 @@ public:
   ///! Get the current time as string
   std::string CurrentTime();
 
+  //! tar/gzip and then base 64 encode a file
+  std::string Base64GzipEncodeFile(std::string file);
+
   /** 
-   * Return the time remaianing that the script is allowed to run in
+   * Return the time remaining that the script is allowed to run in
    * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
    * not been set it returns 1e7 seconds
    */
@@ -515,7 +519,7 @@ private:
   //! Reread the configuration file
   bool UpdateCTestConfiguration();
 
-  //! Create not from files.
+  //! Create note from files.
   int GenerateCTestNotesOutput(std::ostream& os,
     const VectorOfStrings& files);
 

+ 10 - 0
Tests/CMakeLists.txt

@@ -1443,6 +1443,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     PASS_REGULAR_EXPRESSION "Could not find executable"
     FAIL_REGULAR_EXPRESSION "SegFault")
 
+  CONFIGURE_FILE(
+    "${CMake_SOURCE_DIR}/Tests/CTestTestUpload/test.cmake.in"
+    "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake"
+    @ONLY ESCAPE_QUOTES)
+  ADD_TEST(CTestTestUpload ${CMAKE_CTEST_COMMAND}
+    -S "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake" -V
+    --output-log "${CMake_BINARY_DIR}/Tests/CTestTestUpload/testOut.log"
+    )
+  SET_TESTS_PROPERTIES(CTestTestUpload PROPERTIES
+    PASS_REGULAR_EXPRESSION "Upload\\.xml")
 
   # Use macro, not function so that build can still be driven by CMake 2.4.
   # After 2.6 is required, this could be a function without the extra 'set'

+ 4 - 0
Tests/CTestTestUpload/CMakeLists.txt

@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestUpload)
+
+add_executable (Sleep sleep.c)

+ 7 - 0
Tests/CTestTestUpload/CTestConfig.cmake

@@ -0,0 +1,7 @@
+set (CTEST_PROJECT_NAME "CTestTestUpload")
+set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set (CTEST_DART_SERVER_VERSION "2")
+set (CTEST_DROP_METHOD "http")
+set (CTEST_DROP_SITE "www.cdash.org")
+set (CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set (CTEST_DROP_SITE_CDASH TRUE)

+ 21 - 0
Tests/CTestTestUpload/sleep.c

@@ -0,0 +1,21 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for n seconds, where n is the argument to the program */
+int main(int argc, char** argv)
+{
+  int time;
+  if(argc > 1)
+    {
+    time = atoi(argv[1]);
+    }
+#if defined(_WIN32)
+  Sleep(time * 1000);
+#else
+  sleep(time);
+#endif
+  return 0;
+}

+ 17 - 0
Tests/CTestTestUpload/test.cmake.in

@@ -0,0 +1,17 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT                "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE                          "@SITE@")
+SET(CTEST_BUILD_NAME                    "CTestTest-@BUILDNAME@-Upload")
+
+SET(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestUpload")
+SET(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestUpload")
+SET(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+SET(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_UPLOAD("${CTEST_SOURCE_DIRECTORY}/sleep.c" "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt")
+CTEST_SUBMIT()