Skip to content
Snippets Groups Projects
SCARFTomoReconstructionTest.h 24.1 KiB
Newer Older
#ifndef MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_
#define MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_

#include <cxxtest/TestSuite.h>

#include "MantidAPI/ITableWorkspace.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/FacilityInfo.h"
#include "MantidRemoteAlgorithms/SCARFTomoReconstruction.h"

using namespace Mantid::RemoteAlgorithms;

/**
 * Very crude mock up for the interaction with the remote compute
 * resource (in real life, through the PAC web service of the LSF job
 * scheduler on SCARF). This one returns 200 OK and a simple response
 * string.
class MockedSCARFTomo : public SCARFTomoReconstruction {
  int doSendRequestGetResponse(
      const std::string &url, std::ostream &response,
      const StringToStringMap &headers = StringToStringMap(),
      const std::string &method = std::string(),
      const std::string &body = "") override {
    UNUSED_ARG(url);
    UNUSED_ARG(headers);
    UNUSED_ARG(method);
    UNUSED_ARG(body);

    response << "response OK - mocked up";
    return 200;
/**
 * One more crude mock up for the interaction with the remote compute
 * resource. This one returns an error (the connection is fine, but
 * the response from the server is an error; example: wrong path,
 * server bug, etc.).
 */
class MockedErrorResponse_SCARFTomo : public SCARFTomoReconstruction {
  int doSendRequestGetResponse(
      const std::string &url, std::ostream &response,
      const StringToStringMap &headers = StringToStringMap(),
      const std::string &method = std::string(),
      const std::string &body = "") override {
    UNUSED_ARG(url);
    UNUSED_ARG(response);
    UNUSED_ARG(headers);
    UNUSED_ARG(method);
    UNUSED_ARG(body);

    response << "Error response - mocked up";
    return 404;
/**
 * One more crude mock up for the interaction with the remote compute
 * resource. This one raises an exception as if the (underlying)
 * InternetHelper had found a connection issue.
 */
class MockedConnectionError_SCARFTomo : public SCARFTomoReconstruction {
  int doSendRequestGetResponse(
      const std::string &url, std::ostream &response,
      const StringToStringMap &headers = StringToStringMap(),
      const std::string &method = std::string(),
      const std::string &body = "") override {
    UNUSED_ARG(url);
    UNUSED_ARG(response);
    UNUSED_ARG(headers);
    UNUSED_ARG(method);
    UNUSED_ARG(body);

    // throw as if there was a connection error
    throw Mantid::Kernel::Exception::InternetError(
        "Mocked up exception - connection error");
/**
 * One more crude mock up for the interaction with the remote compute
 * resource. This one returns an OK code and a string that reads like
 * what we expect when doing a successful login request.
 */
class MockedGoodLoginResponse_SCARFTomo : public SCARFTomoReconstruction {
  int doSendRequestGetResponse(
      const std::string &url, std::ostream &response,
      const StringToStringMap &headers = StringToStringMap(),
      const std::string &method = std::string(),
      const std::string &body = "") override {
    UNUSED_ARG(url);
    UNUSED_ARG(response);
    UNUSED_ARG(headers);
    UNUSED_ARG(method);
    UNUSED_ARG(body);

    response << "https://portal.scarf.rl.ac.uk - response OK and login "
                "successful - mocked up";
/**
 * One more crude mock up for the interaction with the remote compute
 * resource. This one returns an OK code and a string that reads like
 * a response with basic job status information.
 */
class MockedGoodJobStatus_SCARFTomo : public SCARFTomoReconstruction {
  MockedGoodJobStatus_SCARFTomo(const std::string &id)
      : SCARFTomoReconstruction(), jobID(id){};
  int doSendRequestGetResponse(
      const std::string &url, std::ostream &response,
      const StringToStringMap &headers = StringToStringMap(),
      const std::string &method = std::string(),
      const std::string &body = "") override {
    UNUSED_ARG(url);
    UNUSED_ARG(response);
    UNUSED_ARG(headers);
    UNUSED_ARG(method);
    UNUSED_ARG(body);

    response
        << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
           "<Jobs><Job><cmd>python /work/imat/webservice_test/test.py.py "
           "/work/imat/webservice_test/test_out/</cmd><extStatus>-</extStatus>"
           "<id>" << jobID
        << "</id><name>Mantid_tomography_1</name><status>Running</status>"
           "</Job></Jobs>";
class SCARFTomoReconstructionTest : public CxxTest::TestSuite {
public:
  // This pair of boilerplate methods prevent the suite being created statically
  // This means the constructor isn't called when running other tests
  static SCARFTomoReconstructionTest *createSuite() {
    return new SCARFTomoReconstructionTest();
  }
  static void destroySuite(SCARFTomoReconstructionTest *suite) { delete suite; }

  void setUp() override {
    const Mantid::Kernel::FacilityInfo &fac =
        Mantid::Kernel::ConfigService::Instance().getFacility();
    m_facility = fac.name();
  }

  void test_castAlgorithm() {
    TS_ASSERT(a = boost::make_shared<MockedSCARFTomo>());
    // can cast to inherited interfaces and base classes
    TS_ASSERT(dynamic_cast<Mantid::RemoteAlgorithms::SCARFTomoReconstruction *>(
        &alg));
    TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(&alg));
    TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(&alg));
    TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(&alg));
    TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(&alg));
  void test_initAlgorithm() {
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
  void test_propertiesMissing() {
    TS_ASSERT_THROWS_NOTHING(alg1.initialize());
    TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("UserName", "anything"));
    TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("Action", "LogIn"));
    TS_ASSERT_THROWS_NOTHING(alg1.execute());
    TS_ASSERT(!alg1.isExecuted());
    TS_ASSERT_THROWS_NOTHING(alg2.initialize());
    TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("Password", "whatever"));
    TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("Action", "LogIn"));
    TS_ASSERT_THROWS(alg2.execute(), std::runtime_error);
    TS_ASSERT(!alg2.isExecuted());
    TS_ASSERT_THROWS_NOTHING(alg3.initialize());
    // these try to set inexistent propeties => runtime_error
    TS_ASSERT_THROWS(alg3.setPropertyValue("sername", "anything"),
                     std::runtime_error);
    TS_ASSERT_THROWS(alg3.setPropertyValue("Passw", "anything"),
                     std::runtime_error);
    // these try to set wrong values for valid properties => invalid_argument
    TS_ASSERT_THROWS(alg3.setPropertyValue("Action", "Loggin"),
                     std::invalid_argument);
    TS_ASSERT_THROWS(alg3.setProperty("Action", "unknown_opt"),
                     std::invalid_argument);
    TS_ASSERT_THROWS(alg3.setPropertyValue("JobID", "strings_not_allowed"),
                     std::invalid_argument);
  void test_actionWithoutUsernameBeforeLogin() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());

    // Forget the username and you should get an exception
    // alg.setProperty("UserName", "foo_user"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS(alg.execute(), std::runtime_error);
    TS_ASSERT(!alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "SubmitJob"));
    TS_ASSERT_THROWS(tomo.execute(), std::runtime_error);
    TS_ASSERT(!tomo.isExecuted());
  void test_actionWithoutLogin() {
    // Even if you provide all required params, you should get an exception
    // if not logged in
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS(alg.execute(), std::runtime_error);
    TS_ASSERT(!alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("UserName", "anyone"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "SubmitJob"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("JobOptions", "--test --baz"));

    TS_ASSERT_THROWS_NOTHING(tomo.execute());
    TS_ASSERT(!tomo.isExecuted());
  }

  /// Login is required before running the other actions (except ping)
  // The good username is: foo_user
  void test_login() {
    m_goodUsername = "foo_user";
    m_goodPassword = "foo_password";
    // severe (connection) error
    MockedConnectionError_SCARFTomo err;
    TS_ASSERT_THROWS_NOTHING(err.initialize());
    TS_ASSERT_THROWS_NOTHING(err.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(err.setProperty("Password", m_goodPassword));
    TS_ASSERT_THROWS_NOTHING(err.setProperty("Action", "LogIn"));
    TS_ASSERT_THROWS_NOTHING(err.execute());
    TS_ASSERT(!err.isExecuted());

    // standard mocked response: looks like an unsuccessful login attempt
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Password", m_goodPassword));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "LogIn"));
    TS_ASSERT_THROWS_NOTHING(tomo.execute());
    TS_ASSERT(!tomo.isExecuted());

    // successful login attempt
    MockedGoodLoginResponse_SCARFTomo login;
    TS_ASSERT_THROWS_NOTHING(login.initialize());
    TS_ASSERT_THROWS_NOTHING(login.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(login.setProperty("Password", m_goodPassword));
    TS_ASSERT_THROWS_NOTHING(login.setProperty("Action", "LogIn"));
    TS_ASSERT_THROWS_NOTHING(login.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / login should fail when the facility is not " +
              g_supportedFacility,
          !login.isExecuted());
      return;
    }

    TS_ASSERT(login.isExecuted());
  void test_actionWithoutUsernameAfterLogin() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS(alg.execute(), std::runtime_error);
    TS_ASSERT(!alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    // Forget this and you should get an exception
    // tomo.setProperty("UserName", 3));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "SubmitJob"));
    TS_ASSERT_THROWS(tomo.execute(), std::runtime_error);
    TS_ASSERT(!tomo.isExecuted());
  void test_actionWrongUsername() {
    // Once you log out all actions should produce an exception
    MockedSCARFTomo tomo;
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    TS_ASSERT_THROWS_NOTHING(
        tomo.setProperty("UserName", "fail_" + m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("JobOptions", "--test --baz"));

    TS_ASSERT_THROWS_NOTHING(tomo.execute());
    TS_ASSERT(!tomo.isExecuted());
  void test_wrongExec() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS(alg.setProperty("RandomName", 32), std::runtime_error);
    TS_ASSERT_THROWS(alg.execute(), std::runtime_error);
    TS_ASSERT(!alg.isExecuted());
  void test_ping() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Action", "Ping"));
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Username", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.execute());
    TS_ASSERT(alg.isExecuted());
  void test_submit() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "SubmitJob"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("JobOptions", "--test --baz"));
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / submit should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(tomo.initialize());
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("Action", "SubmitJob"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(tomo.setProperty("JobOptions", "--random --baz"));

    TS_ASSERT_THROWS_NOTHING(tomo.execute());
    TS_ASSERT(tomo.isExecuted());
  void test_queryStatus() {
    // this one is the basic mock up which doesn't provide the response content
    // that we need
    TS_ASSERT_THROWS_NOTHING(err.initialize());
    TS_ASSERT_THROWS_NOTHING(err.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(err.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(err.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / queryStatus should fail when the facility is not " +
              g_supportedFacility,
          !err.isExecuted());
      return;
    }

    TS_ASSERT(err.isExecuted());
    std::vector<std::string> vec;
    TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsID"));
    TS_ASSERT_EQUALS(vec.size(), 0);
    TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsNames"));
    TS_ASSERT_EQUALS(vec.size(), 0);
    TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsStatus"));
    TS_ASSERT_EQUALS(vec.size(), 0);
    TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsCommands"));
    TS_ASSERT_EQUALS(vec.size(), 0);

    // this one gives a basic/sufficient response with job status information
    MockedGoodJobStatus_SCARFTomo alg("wrong id");
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / queryStatus should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
    // the mock produces info on one job
    TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsID"));
    TS_ASSERT_EQUALS(vec.size(), 1);
    TS_ASSERT(vec.size() > 0 && !vec.front().empty());
    TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsNames"));
    TS_ASSERT_EQUALS(vec.size(), 1);
    TS_ASSERT(vec.size() > 0 && !vec.front().empty());
    TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsStatus"));
    TS_ASSERT_EQUALS(vec.size(), 1);
    TS_ASSERT(vec.size() > 0 && !vec.front().empty());
    TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsCommands"));
    TS_ASSERT_EQUALS(vec.size(), 1);
    TS_ASSERT(vec.size() > 0 && !vec.front().empty());
  void test_queryStatusByID() {
    // this one is the basic mockup: doesn't provide the response content that
    // we need
    TS_ASSERT_THROWS_NOTHING(err.initialize());
    TS_ASSERT_THROWS_NOTHING(err.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(err.setProperty("Action", "JobStatusByID"));
    TS_ASSERT_THROWS_NOTHING(err.setProperty("JobID", 123456789));
    TS_ASSERT_THROWS_NOTHING(err.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT("This algorithm / queryStatusByID should fail when the "
                 "facility is not " +
                     g_supportedFacility,
                 !err.isExecuted());
      return;
    }

    TS_ASSERT(err.isExecuted());
    TS_ASSERT_THROWS_NOTHING(tmp = err.getPropertyValue("RemoteJobName"));
    TS_ASSERT(tmp.empty());
    TS_ASSERT_THROWS_NOTHING(tmp = err.getPropertyValue("RemoteJobStatus"));
    TS_ASSERT(tmp.empty());
    TS_ASSERT_THROWS_NOTHING(tmp = err.getPropertyValue("RemoteJobsCommands"));
    TS_ASSERT(tmp.empty());

    // this one gives a basic/sufficient response with job status information
    std::string jobID = "444449";
    MockedGoodJobStatus_SCARFTomo alg(jobID);
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatusByID"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("JobID", jobID));

    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT("This algorithm / queryStatusByID should fail when the "
                 "facility is not " +
                     g_supportedFacility,
                 !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());

    // It could also check that it gets the names, etc. that the mock-up
    // produces
    TS_ASSERT_THROWS_NOTHING(tmp = alg.getPropertyValue("RemoteJobName"));
    TS_ASSERT(!tmp.empty());
    TS_ASSERT_THROWS_NOTHING(tmp = alg.getPropertyValue("RemoteJobStatus"));
    TS_ASSERT(!tmp.empty());
    TS_ASSERT_THROWS_NOTHING(tmp = alg.getPropertyValue("RemoteJobCommand"));
    TS_ASSERT(!tmp.empty());
  void test_cancel() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "CancelJob"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("CancelJobID", 123456789));
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / cancel should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
  void test_upload() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Username", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "Upload"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("FileToUpload", "random_file"));
    TS_ASSERT_THROWS_NOTHING(
        alg.setProperty("DestinationDirectory", "random_path/"));

    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / upload should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
  void test_download() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());

    // Download with empty filename (get all files)
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "Download"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("DownloadJobID", 12345));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("RemoteJobFilename", ""));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LocalDirectory", "/tmp/foo"));
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / download should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(alg2.initialize());
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("Action", "Download"));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("DownloadJobID", 12345));
    TS_ASSERT_THROWS_NOTHING(
        alg2.setProperty("RemoteJobFilename", "inexistent_test_name.nxs.foo"));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("LocalDirectory", "/tmp/foo"));
    TS_ASSERT_THROWS_NOTHING(alg2.execute());
    TS_ASSERT(!alg2.isExecuted());
  void test_errorResponseFromServer() {
    MockedErrorResponse_SCARFTomo err;
    TS_ASSERT_THROWS_NOTHING(err.initialize());
    TS_ASSERT_THROWS_NOTHING(err.setPropertyValue("Username", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(err.setPropertyValue("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(err.execute());
    TS_ASSERT(!err.isExecuted());
  }

  // logout must run after all the (positive) tests
  void test_logout() {
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "LogOut"));
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    if (g_supportedFacility != m_facility) {
      TSM_ASSERT(
          "This algorithm / logout should fail when the facility is not " +
              g_supportedFacility,
          !alg.isExecuted());
      return;
    }

    TS_ASSERT(alg.isExecuted());
  void test_actionAfterLogout() {
    // Once you log out all actions should produce an exception, regardless of
    // the username given
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT_THROWS_NOTHING(
        alg.setProperty("UserName", "fail_" + m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("JobOptions", "--test --baz"));

    TS_ASSERT_THROWS_NOTHING(alg.execute());
    TS_ASSERT(!alg.isExecuted());
    TS_ASSERT_THROWS_NOTHING(alg2.initialize());
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("UserName", m_goodUsername));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("Action", "JobStatus"));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("RunnablePath", "/foo/bar.sh"));
    TS_ASSERT_THROWS_NOTHING(alg2.setProperty("JobOptions", "--test --baz"));

    TS_ASSERT_THROWS_NOTHING(alg2.execute());
    TS_ASSERT(!alg2.isExecuted());
  void test_failConnect() {
    MockedConnectionError_SCARFTomo fail;
    TS_ASSERT_THROWS_NOTHING(fail.initialize());
    TS_ASSERT_THROWS_NOTHING(fail.setPropertyValue("Action", "Ping"));
    TS_ASSERT_THROWS(fail.execute(), std::runtime_error);
    TS_ASSERT(!fail.isExecuted());

    MockedConnectionError_SCARFTomo fail2;
    TS_ASSERT_THROWS_NOTHING(fail2.initialize());
    TS_ASSERT_THROWS_NOTHING(fail2.setPropertyValue("Username", "uname"));
    TS_ASSERT_THROWS_NOTHING(fail2.setPropertyValue("Password", "whatever"));
    TS_ASSERT_THROWS_NOTHING(fail2.setPropertyValue("Action", "LogIn"));
    TS_ASSERT_THROWS_NOTHING(fail2.execute());
    TS_ASSERT(!fail2.isExecuted());
  void test_errorResponseFromServerAfterLogout() {
    MockedErrorResponse_SCARFTomo err;
    TS_ASSERT_THROWS_NOTHING(err.initialize());
    TS_ASSERT_THROWS_NOTHING(err.setPropertyValue("Username", "foo"));
    TS_ASSERT_THROWS_NOTHING(err.setPropertyValue("Action", "Ping"));
    TS_ASSERT_THROWS_NOTHING(err.execute());
    TS_ASSERT(!err.isExecuted());
  std::string m_goodUsername;
  std::string m_goodPassword;
  std::string m_facility;
  static const std::string g_supportedFacility;
  static const std::string g_SCARFName;
const std::string SCARFTomoReconstructionTest::g_SCARFName = "SCARF@STFC";
// This algorithm work only for ISIS
const std::string SCARFTomoReconstructionTest::g_supportedFacility = "ISIS";
#endif // MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_