AlgorithmHistoryTest.h 9.18 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
#pragma once
Dickon Champion's avatar
re #58  
Dickon Champion committed
8

9
#include "MantidAPI/Algorithm.h"
Dickon Champion's avatar
re #58  
Dickon Champion committed
10
11
#include "MantidAPI/AlgorithmHistory.h"
#include "MantidAPI/WorkspaceProperty.h"
LamarMoore's avatar
LamarMoore committed
12
#include <cxxtest/TestSuite.h>
Nick Draper's avatar
Re #88    
Nick Draper committed
13
#include <sstream>
Dickon Champion's avatar
re #58  
Dickon Champion committed
14
15

using namespace Mantid::API;
16
using namespace Mantid::Kernel;
Dickon Champion's avatar
re #58  
Dickon Champion committed
17

18
// 'Empty' algorithm class for tests
19
class testalg : public Algorithm {
20
21
public:
  testalg() : Algorithm() {}
22
23
  ~testalg() override {}
  const std::string name() const override {
24
    return "testalg";
Hahn, Steven's avatar
Hahn, Steven committed
25
  } ///< Algorithm's name for identification
26
27
28
29
  int version() const override {
    return 1;
  } ///< Algorithm's version for identification
  const std::string category() const override {
30
31
    return "Cat";
  } ///< Algorithm's category for identification
32
  const std::string summary() const override { return "Test summary"; }
33

34
  void init() override {
35
36
    declareProperty("arg1_param", "x", Direction::Input);
    declareProperty("arg2_param", 23);
37
  }
38
  void exec() override {}
39
};
Dickon Champion's avatar
re #58  
Dickon Champion committed
40

41
class AlgorithmHistoryTest : public CxxTest::TestSuite {
Dickon Champion's avatar
re #58  
Dickon Champion committed
42
public:
43
  AlgorithmHistoryTest() : m_correctOutput(), m_execCount(0) {}
Nick Draper's avatar
Re #88    
Nick Draper committed
44

45
  void testPopulate() {
46
    AlgorithmHistory AH = createTestHistory();
47
    // dump output to sting
Nick Draper's avatar
Re #88    
Nick Draper committed
48
    std::ostringstream output;
49
    output.exceptions(std::ios::failbit | std::ios::badbit);
Nick Draper's avatar
Re #88    
Nick Draper committed
50
    TS_ASSERT_THROWS_NOTHING(output << AH);
51
52
53
54
55
56
57

    // Remove UUID line from output
    std::string outputStr = output.str();
    // 44 is the expected length of the UUID string
    outputStr.erase(outputStr.find("UUID: "), 43);

    TS_ASSERT_EQUALS(outputStr, m_correctOutput);
58
59
60
    // Does it equal itself
    TS_ASSERT_EQUALS(AH, AH);
  }
Dickon Champion's avatar
re #58  
Dickon Champion committed
61

Samuel Jones's avatar
Samuel Jones committed
62
63
64
65
66
67
  void test_Less_Than_Returns_True_For_If_Execution_Order_Is_Lower() {
    AlgorithmHistory first = createTestHistory();
    AlgorithmHistory second = createTestHistory();
    TS_ASSERT_LESS_THAN(first, second);
  }

68
69
  void test_getPropertyValue() {
    AlgorithmHistory alg = createTestHistory();
70
    TS_ASSERT_EQUALS(alg.getPropertyValue("arg1_param"), "y");
71
72
73
74
    TS_ASSERT_EQUALS(alg.getPropertyValue("arg2_param"), "23");
    TS_ASSERT_THROWS_ANYTHING(alg.getPropertyValue("none_existant"));
  }

75
  void test_Created_Algorithm_Matches_History() {
76
77
78
79
    Mantid::API::AlgorithmFactory::Instance().subscribe<testalg>();
    Algorithm *testInput = new testalg;
    testInput->initialize();
    testInput->setPropertyValue("arg2_param", "5");
80
    AlgorithmHistory history(testInput);
81

82
83
84
85
    IAlgorithm_sptr compareAlg = history.createAlgorithm();
    TS_ASSERT_EQUALS(compareAlg->name(), testInput->name());
    TS_ASSERT_EQUALS(compareAlg->version(), testInput->version());
    TS_ASSERT_EQUALS(compareAlg->category(), testInput->category());
86

87
88
    TS_ASSERT_EQUALS(compareAlg->getPropertyValue("arg1_param"), "x");
    TS_ASSERT_EQUALS(compareAlg->getPropertyValue("arg2_param"), "5");
89
90
91

    Mantid::API::AlgorithmFactory::Instance().unsubscribe(testInput->name(),
                                                          testInput->version());
92
    delete testInput;
93
  }
Dickon Champion's avatar
re #58  
Dickon Champion committed
94

95
  void test_Nested_History() {
96
97
    Mantid::API::AlgorithmFactory::Instance().subscribe<testalg>();
    Algorithm *testInput = new testalg;
98
99
    using namespace Mantid::API;
    AlgorithmHistory algHist = createTestHistory();
100
101

    // create some nested history records
102
103
    auto child1 = createFromTestAlg("child1");
    auto subChild11 = createFromTestAlg("subChild11");
104
    child1.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild11));
105

106
107
108
    auto child2 = createFromTestAlg("child2");
    auto subChild21 = createFromTestAlg("subChild21");
    auto subChild22 = createFromTestAlg("subChild22");
109
110
    child2.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild21));
    child2.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild22));
111

112
113
    auto child3 = createFromTestAlg("child3");

114
115
116
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child1));
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child2));
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child3));
117

118
    // check parent algorithm matches
119
    std::ostringstream output;
120
    output.exceptions(std::ios::failbit | std::ios::badbit);
121
    TS_ASSERT_THROWS_NOTHING(output << algHist);
122
123
124
125
126
127
128

    // Remove UUID line from output
    std::string outputStr = output.str();
    // 44 is the expected length of the UUID string
    outputStr.erase(outputStr.find("UUID: "), 43);

    TS_ASSERT_EQUALS(outputStr, m_correctOutput);
129
130
131

    auto children = algHist.getChildHistories();
    TS_ASSERT_EQUALS(children.size(), 3);
132
133

    // check children are valid
134
135
    int i = 1;
    AlgorithmHistories::iterator it;
136
    for (it = children.begin(); it != children.end(); ++it, ++i) {
137
      IAlgorithm_sptr childAlg = (*it)->createAlgorithm();
138
      std::string index = boost::lexical_cast<std::string>(i);
139
140
      TS_ASSERT_EQUALS(childAlg->getPropertyValue("arg1_param"),
                       "child" + index);
141

142
      // check sub children
143
      auto subchildren = (*it)->getChildHistories();
144
145
      int j = 1;
      AlgorithmHistories::iterator jt;
146
      for (jt = subchildren.begin(); jt != subchildren.end(); ++j, ++jt) {
147
        IAlgorithm_sptr subChildAlg = (*jt)->createAlgorithm();
148
        std::string subindex = boost::lexical_cast<std::string>(j);
149
150
151
        TS_ASSERT_EQUALS(subChildAlg->getPropertyValue("arg1_param"),
                         "subChild" + index + subindex);
      }
152
    }
153
154
    Mantid::API::AlgorithmFactory::Instance().unsubscribe(testInput->name(),
                                                          testInput->version());
155
156
157
    delete testInput;
  }

158
  void test_Create_Child_Algorithm() {
159
160
161
162
    AlgorithmFactory::Instance().subscribe<testalg>();
    Algorithm *testInput = new testalg;
    using namespace Mantid::API;
    AlgorithmHistory algHist = createTestHistory();
163
164

    // create some nested history records
165
166
    auto child1 = createFromTestAlg("child1");
    auto subChild11 = createFromTestAlg("subChild11");
167
    child1.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild11));
168

169
170
171
    auto child2 = createFromTestAlg("child2");
    auto subChild21 = createFromTestAlg("subChild21");
    auto subChild22 = createFromTestAlg("subChild22");
172
173
    child2.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild21));
    child2.addChildHistory(boost::make_shared<AlgorithmHistory>(subChild22));
174

175
    auto child3 = createFromTestAlg("child3");
176

177
178
179
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child1));
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child2));
    algHist.addChildHistory(boost::make_shared<AlgorithmHistory>(child3));
180
181
182
183
184

    IAlgorithm_sptr alg = algHist.getChildAlgorithm(0);
    TS_ASSERT_EQUALS(alg->name(), testInput->name());
    TS_ASSERT_EQUALS(alg->version(), testInput->version());
    TS_ASSERT_EQUALS(alg->category(), testInput->category());
185
186
187

    Mantid::API::AlgorithmFactory::Instance().unsubscribe(testInput->name(),
                                                          testInput->version());
188
    delete testInput;
189

190
    TS_ASSERT_EQUALS(alg->getPropertyValue("arg1_param"), "child1");
191
192
  }

193
private:
194
  AlgorithmHistory createTestHistory() {
195
    m_correctOutput = "Algorithm: testalg ";
196
    m_correctOutput += "v1\n";
197
    m_correctOutput += "Execution Date: 2008-02-29 09:54:49\n";
198
    m_correctOutput += "Execution Duration: 14 seconds\n";
199
200
    // This line is newer than the rest and cannot be predicted
    // m_correctOutput += "UUID: 207ca8f8-fee0-49ce-86c8-7842a7313c2e\n";
201
202
203
204
205
206
207
208
209
210
211
    m_correctOutput += "Parameters:\n";
    m_correctOutput += "  Name: arg1_param, ";
    m_correctOutput += "Value: y, ";
    m_correctOutput += "Default?: No, ";
    m_correctOutput += "Direction: Input\n";
    m_correctOutput += "  Name: arg2_param, ";
    m_correctOutput += "Value: 23, ";
    m_correctOutput += "Default?: Yes, ";
    m_correctOutput += "Direction: Input\n";

    // set the time
212
    std::time_t rawtime;
213
    std::tm *timeinfo = new std::tm;
214
215
216
    timeinfo->tm_isdst = -1;

    /* The datetime must match that in the strng above */
217
    std::time(&rawtime);
218
219
220
221
222
223
    timeinfo->tm_year = 108;
    timeinfo->tm_mon = 1;
    timeinfo->tm_mday = 29;
    timeinfo->tm_hour = 9;
    timeinfo->tm_min = 54;
    timeinfo->tm_sec = 49;
224
    // Convert to time_t but assuming the tm is specified in UTC time.
LamarMoore's avatar
LamarMoore committed
225
226
    std::time_t execTime_t =
        Mantid::Types::Core::DateAndTime::utc_mktime(timeinfo);
227
    // Create a UTC datetime from it
228
    Mantid::Types::Core::DateAndTime execTime;
229
    execTime.set_from_time_t(execTime_t);
230
231
232
233
234
235
236
237
238

    // Not really much to test
    testalg alg;
    alg.initialize();
    alg.setPropertyValue("arg1_param", "y");
    alg.execute();

    delete timeinfo;

239
    return AlgorithmHistory(&alg, execTime, 14.0, m_execCount++);
240
241
  }

David Fairbrother's avatar
David Fairbrother committed
242
  AlgorithmHistory createFromTestAlg(const std::string &paramValue) {
243
244
245
    Algorithm *testInput = new testalg;
    testInput->initialize();
    testInput->setPropertyValue("arg1_param", paramValue);
246
    AlgorithmHistory history(testInput, 1, -1.0, m_execCount++);
247
248
249
250
251

    delete testInput;
    return history;
  }

252
253
  std::string m_correctOutput;
  size_t m_execCount;
Dickon Champion's avatar
re #58  
Dickon Champion committed
254
};