SL-18837: Try to bypass Windows perm problem with Python indirection.

master
Nat Goodspeed 2023-07-07 14:07:12 -04:00
parent f54c121567
commit e933ace53b
3 changed files with 58 additions and 25 deletions

View File

@ -124,6 +124,17 @@ void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60)
i < timeout);
}
namespace {
// find test helper, a sibling of this file
// nat 2023-07-07: we're currently using Boost 1.81, but
// path::replace_filename() (which is exactly what we need here) doesn't
// arrive until Boost 1.82.
auto test_python_script{
(boost::filesystem::path(__FILE__).remove_filename() / "test_python_script.py").string() };
}
/**
* Construct an LLProcess to run a Python script.
*/
@ -145,6 +156,7 @@ struct PythonProcessLauncher
mParams.desc = desc + " script";
mParams.executable = PYTHON;
mParams.args.add(test_python_script);
mParams.args.add(mScript.getName());
}
@ -214,30 +226,26 @@ static std::string python_out(const std::string& desc, const CONTENT& script)
class NamedTempDir: public boost::noncopyable
{
public:
// Use python() function to create a temp directory: I've found
// nothing in either Boost.Filesystem or APR quite like Python's
// tempfile.mkdtemp().
// Special extra bonus: on Mac, mkdtemp() reports a pathname
// starting with /var/folders/something, whereas that's really a
// symlink to /private/var/folders/something. Have to use
// realpath() to compare properly.
NamedTempDir():
mPath(python_out("mkdtemp()",
"from __future__ import with_statement\n"
"import os.path, sys, tempfile\n"
"with open(sys.argv[1], 'w') as f:\n"
" f.write(os.path.normcase(os.path.normpath(os.path.realpath(tempfile.mkdtemp()))))\n"))
{}
mPath(NamedTempFile::temp_path()),
mCreated(boost::filesystem::create_directories(mPath))
{
mPath = boost::filesystem::canonical(mPath);
}
~NamedTempDir()
{
aprchk(apr_dir_remove(mPath.c_str(), gAPRPoolp));
if (mCreated)
{
boost::filesystem::remove_all(mPath);
}
}
std::string getName() const { return mPath; }
std::string getName() const { return mPath.string(); }
private:
std::string mPath;
boost::filesystem::path mPath;
bool mCreated;
};
/*****************************************************************************
@ -390,6 +398,7 @@ namespace tut
// Have to have a named copy of this std::string so its c_str() value
// will persist.
std::string scriptname(script.getName());
argv.push_back(test_python_script.c_str());
argv.push_back(scriptname.c_str());
argv.push_back(NULL);

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
"""\
@file test_python_script.py
@author Nat Goodspeed
@date 2023-07-07
@brief Work around a problem running Python within integration tests on GitHub
Windows runners.
$LicenseInfo:firstyear=2023&license=viewerlgpl$
Copyright (c) 2023, Linden Research, Inc.
$/LicenseInfo$
"""
import os
import sys
# use pop() so that if the referenced script in turn looks at sys.argv, it
# will see its arguments rather than its own filename
_script = sys.argv.pop(1)
exec(open(_script).read())

View File

@ -65,8 +65,7 @@ public:
boost::filesystem::remove(mPath);
}
// On Windows, path::native() returns a wstring
std::string getName() const { return ll_convert<std::string>(mPath.native()); }
std::string getName() const { return mPath.string(); }
void peep()
{
@ -78,12 +77,9 @@ public:
std::cout << "---\n";
}
protected:
void createFile(const std::string_view& pfx,
const Streamer& func,
const std::string_view& sfx)
static boost::filesystem::path temp_path(const std::string_view& pfx="",
const std::string_view& sfx="")
{
// Create file in a temporary place.
// This variable is set by GitHub actions and is the recommended place
// to put temp files belonging to an actions job.
const char* RUNNER_TEMP = getenv("RUNNER_TEMP");
@ -97,9 +93,17 @@ protected:
// with underscores instead of hyphens: some use cases involve
// temporary Python scripts
tempdir / stringize(pfx, "%%%%_%%%%_%%%%_%%%%", sfx) };
mPath = boost::filesystem::unique_path(tempname);
boost::filesystem::ofstream out{ mPath };
return boost::filesystem::unique_path(tempname);
}
protected:
void createFile(const std::string_view& pfx,
const Streamer& func,
const std::string_view& sfx)
{
// Create file in a temporary place.
mPath = temp_path(pfx, sfx);
boost::filesystem::ofstream out{ mPath };
// Write desired content.
func(out);
}