Commit 87172a94 authored by Nikita Sirgienko's avatar Nikita Sirgienko
Browse files

[Octave] Add check, if Octave can have write in temporary dir

BUG: 420959
FIXED-IN: 20.07.70
parent 6fe27cc1
......@@ -39,11 +39,12 @@ target_link_libraries(cantor_octavebackend
if(BUILD_TESTING)
add_executable( testoctave testoctave.cpp octaveexpression.cpp settings.cpp)
add_executable( testoctave testoctave.cpp ${OctaveBackend_SRCS})
add_test(NAME testoctave COMMAND testoctave)
ecm_mark_as_test(testoctave)
target_link_libraries( testoctave
Qt5::Test
KF5::SyntaxHighlighting
cantorlibs
cantortest
)
......
......@@ -94,7 +94,7 @@ void OctaveExpression::evaluate()
qDebug() << "evaluate";
QString cmd = command();
QStringList cmdWords = cmd.split(QRegularExpression(QStringLiteral("\\b")), QString::SkipEmptyParts);
if (OctaveSettings::integratePlots() && !cmdWords.contains(QLatin1String("help")) && !cmdWords.contains(QLatin1String("completion_matches")))
if (static_cast<OctaveSession*>(session())->isIntegratedPlotsEnabled() && !cmdWords.contains(QLatin1String("help")) && !cmdWords.contains(QLatin1String("completion_matches")))
{
for (const QString& plotCmd : plotCommands)
{
......
......@@ -24,12 +24,14 @@
#include "octavehighlighter.h"
#include "result.h"
#include "textresult.h"
#include <backend.h>
#include "settings.h"
#include <KProcess>
#include <KDirWatch>
#include <KLocalizedString>
#include <KMessageBox>
#include <QTimer>
#include <QFile>
......@@ -49,7 +51,8 @@ m_process(nullptr),
m_prompt(QStringLiteral("CANTOR_OCTAVE_BACKEND_PROMPT:([0-9]+)> ")),
m_subprompt(QStringLiteral("CANTOR_OCTAVE_BACKEND_SUBPROMPT:([0-9]+)> ")),
m_previousPromptNumber(1),
m_syntaxError(false)
m_syntaxError(false),
m_isIntegratedPlotsEnabled(false)
{
setVariableModel(new OctaveVariableModel(this));
}
......@@ -72,6 +75,44 @@ void OctaveSession::login()
emit loginStarted();
bool isIntegratedPlots = OctaveSettings::integratePlots();
QString tmpWritableErrorReason;
if (isIntegratedPlots)
{
QString filename = QDir::tempPath() + QLatin1String("/cantor_octave_plot_integration_test.txt");
QFile::remove(filename); // Remove previous file, if precents
int test_number = rand() % 1000;
QStringList args;
args << QLatin1String("--no-init-file");
args << QLatin1String("--no-gui");
args << QLatin1String("--eval");
args << QString::fromLatin1("file_id = fopen('%1', 'w'); fdisp(file_id, %2); fclose(file_id);").arg(filename).arg(test_number);
QString errorMsg;
isIntegratedPlots = Cantor::Backend::testProgramWritable(
OctaveSettings::path().toLocalFile(),
args,
filename,
QString::number(test_number),
&errorMsg
);
// If we in this branch, then isIntegratedPlots was true, but if it false now, then it means, that the writabl test is failed
if (isIntegratedPlots == false)
{
KMessageBox::error(nullptr,
i18n("Plot integration test failed.")+
QLatin1String("\n\n")+
errorMsg+
QLatin1String("\n\n")+
i18n("The integration of plots will be disabled."),
i18n("Cantor")
);
}
}
m_isIntegratedPlotsEnabled = isIntegratedPlots;
m_process = new KProcess ( this );
QStringList args;
args << QLatin1String("--silent");
......@@ -98,7 +139,7 @@ void OctaveSession::login()
args << QLatin1String("--eval");
args << QLatin1String("suppress_verbose_help_message(1);");
if (OctaveSettings::integratePlots())
if (isIntegratedPlots)
{
// Do not show the popup when plotting, rather only print to a file
args << QLatin1String("--eval");
......@@ -341,3 +382,8 @@ bool OctaveSession::isSpecialOctaveCommand(const QString& command)
{
return command.contains(QLatin1String("completion_matches"));
}
bool OctaveSession::isIntegratedPlotsEnabled() const
{
return m_isIntegratedPlotsEnabled;
}
......@@ -50,6 +50,8 @@ class OctaveSession : public Cantor::Session
QSyntaxHighlighter* syntaxHighlighter(QObject* parent) override;
void runFirstExpression() override;
bool isIntegratedPlotsEnabled() const;
private:
const static QRegularExpression PROMPT_UNCHANGEABLE_COMMAND;
......@@ -63,6 +65,7 @@ class OctaveSession : public Cantor::Session
bool m_syntaxError;
QString m_output;
bool m_isIntegratedPlotsEnabled; // Better move it in worksheet, like isCompletion, etc.
private:
void readFromOctave(QByteArray data);
......
......@@ -92,7 +92,7 @@ if(LIBSPECTRE_FOUND)
target_link_libraries(cantorlibs ${LIBSPECTRE_LIBRARY})
endif(LIBSPECTRE_FOUND)
set (CANTORLIBS_SOVERSION 24)
set (CANTORLIBS_SOVERSION 25)
set_target_properties( cantorlibs PROPERTIES VERSION ${RELEASE_SERVICE_VERSION} SOVERSION ${CANTORLIBS_SOVERSION})
ecm_setup_version(${RELEASE_SERVICE_VERSION}
......
......@@ -24,6 +24,7 @@
#include <QDir>
#include <QRegularExpression>
#include <QUrl>
#include <QProcess>
#include <KPluginMetaData>
#include <KLocalizedString>
......@@ -210,3 +211,40 @@ bool Backend::checkExecutable(const QString& name, const QString& path, QString*
return true;
}
bool Cantor::Backend::testProgramWritable(const QString& program, const QStringList& args, const QString& filename, const QString& expectedContent, QString* reason, int timeOut)
{
QProcess process;
process.setProgram(program);
process.setArguments(args);
process.start();
if (process.waitForFinished(timeOut) == false)
{
if (reason)
*reason = i18n("The program %1 didn't finish the execution after %2 milliseconds during the plot integration test.", QFileInfo(program).fileName(), timeOut);
return false;
}
QFile file(filename);
if (!file.open(QIODevice::ReadOnly))
{
if (reason)
*reason = i18n("Failed to open the file %1 during the plot integration test.", filename);
return false;
}
QString fileContent = QString::fromLocal8Bit(file.readAll());
if (fileContent.trimmed() != expectedContent)
{
if (reason)
*reason = i18n("Failed to parse the result during the plot integration test.");
return false;
}
file.close();
file.remove();
return true;
}
......@@ -215,7 +215,14 @@ class CANTOR_EXPORT Backend : public QObject, public KXMLGUIClient
* for the backend @c Name with the path to the executable @c path and false otherwise.
* In case the requrements are not fulfilled, the reason is written to @c reason.
*/
static bool checkExecutable(const QString& name, const QString& path, QString* reason);
static bool checkExecutable(const QString& name, const QString& path, QString* reason = nullptr);
/**
*
*/
static bool testProgramWritable(
const QString& program, const QStringList& args, const QString& filename, const QString& expectedContent, QString* reason = nullptr, int timeOut = 5000
);
private:
BackendPrivate* d;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment