Search code examples
matlabperformanceunit-testingjenkinswarm-up

Jenkins - How To Keep Matlab Warmed Up


I'm running Jenkins on a project written in Matlab. My build script is starting up Matlab with necessary arguments to run build script and exits.

As Matlab is an interpreted language, consecutive runs are dramatically faster so I'm trying to find a way to run Matlab and keep it open for future tests.

I also don't think this problem is related to Matlab only, Java is the same.

So the question is: Is there a way to keep process (Matlab in my case) open for future test runs?

Answers about a solution to Java or another interpreted language is welcome.


Solution

  • Disclaimer: I've never tried the following suggestion, and there might be difficulties I haven't considered. But I think it would probably work.

    I think you should be able to use either the MATLAB Engine for Python (R2014b and above) or MATLAB Engine for Java (R2016b and above).

    Instead of starting MATLAB each time you run a Jenkins job, start it once, with matlab -r 'matlab.engine.shareEngine'. This will run the MATLAB command matlab.engine.shareEngine at startup, making MATLAB available for connections from Python or Java.

    Your Jenkins job could then run a small Python or Java script that would connect to the running MATLAB session, execute your testing code, clear up, and disconnect from MATLAB.

    You'd need to make sure to pass back a result from MATLAB to Python/Java to indicate whether your tests had passed or failed, and then cause the Python/Java to exit with a status code reflecting that, so that Jenkins knows about the success/failure.

    You'd also need to take care to clean up at the end of each run, as MATLAB would otherwise end up sharing state between test runs. And you'll also need to make sure that your test runs never crash MATLAB (or have some way of monitoring it and bringing it back up if it does crash).


    Edit: Example as requested.

    So (assuming you have a session of MATLAB running, that has been set up eith a shared as described above) you can connect to MATLAB from Python, and run your tests, using something like the following:

    import matlab.engine
    eng = matlab.engine.connect_matlab()
    import StringIO
    out = StringIO.StringIO()
    err = StringIO.StringIO()
    ret = eng.runmytests(nargout=1,stdout=out,stderr=err)
    print(out.getvalue())
    print(err.getvalue())
    if ret:
        sys.exit(0)
    else:
        sys.exit(1)
    

    Notice the eng.runmytests. Here you are calling a MATLAB function runmytests. You would want to implement a MATLAB function runmytests.m that does something like the following:

    function output = runmytests
    import matlab.unittest.TestSuite;
    try
        suite = TestSuite.fromPackage('testcases','IncludingSubpackages',true);
        results = run(suite);
        display(results);
    catch e
        display(getReport(e,'extended'));
        output = false;
        return
    end
    output = ~any([results.Failed]);
    

    The above example is not completely worked through; I'm afraid I don't have a Python environment on my machine right now to be able to test it out - you'll probably need to tweak it somewhat. But I hope it might be a decent starting point.