Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit tests for pydy/viz/server.py #325

Closed
wants to merge 10 commits into from
Closed

Unit tests for pydy/viz/server.py #325

wants to merge 10 commits into from

Conversation

kdexd
Copy link

@kdexd kdexd commented Feb 2, 2016

  • This PR is in correspondence to issue server.py needs unit tests #243 and contains work on a newly added file under the directory structure as : pydy/viz/tests/test_server.py
  • These tests are for the file : pydy/viz/server.py

Makes a new class `TestStoppableHTTPServer`.
 - Adds method test_stoppable_http_server which tests whether the
   StoppableHttpServer binds and stops properly.

 - Test is passed when the boolean `run` of StoppableHTTPServer
   toggles True/ False on binding/ stopping the server.
@kdexd
Copy link
Author

kdexd commented Feb 2, 2016

@moorepants I will keep on adding more tests incrementally. Currently, I wrote tests for the StoppableHTTPServer class in server.py.Please view the commit message and the code, and suggest me improvements as I am new to test driven development procedure.


def test_stoppable_http_server(self):
self.stoppable_http_server.server_bind()
assert self.stoppable_http_server.run is True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid comparing boolean values to True or False using == or is.
https://www.python.org/dev/peps/pep-0008/#programming-recommendations

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll fix this.

@moorepants
Copy link
Member

If you need some sample data for a scene check out the tests for the scene class. It generates some base data.

 - self.http_server declaration was not used anywhere so removed
 - boolean comparison using `is` refactored
@kdexd
Copy link
Author

kdexd commented Feb 3, 2016

  • Well, I was able to generate two JSON files, one containing scene data, other containing visualization data. Only the JSON file containing scene data is of my interest for server class testing.
  • The files are generated through scene tests, so they cannot be generated and deleted in the server tests, as if the scene tests fail by chance, the server tests will also fail -- though generating JSON was not the task of server.
  • I am thinking of keeping a sample JSON file permanently under the static directory exclusively for server tests, this way the tests will stay independent of each other.
  • Is this way appropriate? Please suggest better workarounds if any..

@kdexd
Copy link
Author

kdexd commented Feb 3, 2016

About my previous comment, I need not generate JSON files for the purpose, I found them under static/js/tests/sample_data directory.

@oliverlee
Copy link
Contributor

For future reference, the output of one test should never be dependent on another. It's better to generate data at the beginning of the test or to add test data files.

 - The method `test_run_server` is broken and needs fix.
@kdexd
Copy link
Author

kdexd commented Feb 3, 2016

I can't find a suitable way to stop the server. Help needed here. The test here won't pass in this commit.

@oliverlee
Copy link
Contributor

You can click on the red x to look at the test failure details. You can then look at the console output for each job to see why your test is failing.

The test fails before the server starts running.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

  • Strange.. I gives as OSError, I didn't face it when I ran nosetests on my machine.
  • I will have to change directory of Server class from static/ to ../static/ to overcome this error.
  • Also, running the server opens the browser by default, which should be separated out in my opinion, as a person might want to open the browser later. We are anyways printing in the command line, that visit this URL from your browser..

@moorepants
Copy link
Member

IPython opens the server by default. I think we were copying that functionality here.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

Shifting the line webbrowser.open(url) to a separate method does not open the server.

Also I need to perform assertions and further shutdown the server by sending it SIGINT and a "Y" as stdin. But on running the tests, the server starts and nothing can be performed further.

I tried to use subprocess, in the previous commit, but the method subprocess.communicate waits for the process to end.

On manually stopping the server, I get an EOFError, due to killing of the subprocess and this test fails.

What should I do for it?

@oliverlee
Copy link
Contributor

You call communicate() twice, the first with no input. As it has no input, the first call will never terminate.

Call communicate() once and with input and then use wait() with a timeout.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

@oliverlee This trick doesn't work as the test does not move on to next line of execution once the server is started.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

@oliverlee @moorepants Hi, while testing run_server, the moment I execute it, the server starts and the test does not move further as it waits for the server to stop. I have tried multiprocessing.Process, multiprocessing.Pool, subprocess, thread, threading.

None seem to just open the server in the background and let me programatically generate an interrupt and further provide a "y" as stdin, to shutdown the server.

I thought the thread or threading modules will surely help, but the method contains a signal.signal, which is only valid in main thread.

What should I do here now ?

@oliverlee
Copy link
Contributor

If you comment out the code, I cannot see how the test fails on Travis.

@oliverlee
Copy link
Contributor

The subprocess/Popen module is used to spawn new processes and is intended to replace several older modules and functions, namely os.system. https://docs.python.org/3/library/subprocess.html

We want to run the server in another thread as the current behavior blocks. I've submitted #326 to move execution into a background thread allowing you to stop it easily.

Here's an example:

    def test_run_server(self):
        self.test_server.run_server(headless=True)
        assert self.test_server.httpd.running

        sys.stdin = io.StringIO('y')
        os.kill(os.getpid(), signal.SIGINT)
        assert not self.test_server.httpd.running
        assert not self.test_server._thread.is_alive()

@oliverlee
Copy link
Contributor

I don't know what directory you're running the tests in, but it fails on travis:

======================================================================
ERROR: pydy.viz.tests.test_server.TestServer.test_run_server
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/miniconda/envs/test-env/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/travis/build/pydy/pydy/pydy/viz/tests/test_server.py", line 41, in test_run_server
    proc = subprocess.Popen(self.test_server.run_server(),
  File "/home/travis/build/pydy/pydy/pydy/viz/server.py", line 81, in run_server
    os.chdir(self.directory)
OSError: [Errno 2] No such file or directory: '../static/'

You need to set the directory argument of Server during initialization.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

@oliverlee That is because after one test, the directory cannot be changed to static/ again as we get into static/ for the first time.

This happened on my machine too. I executed os.chdir("..") to get out of the static/ directory after doing the tests.

Does travis test in the same container as appveyor ? It seems strange as I could see one test passing and another failing afterwards sometime ago.

@oliverlee
Copy link
Contributor

The directory argument is not set correctly because the working directory on travis is likely different than what you are using. Something like this will set the correct directory regardless of your working directory:

os.path.join(os.path.dirname(__file__), '../static')

However, I don't know if the server will modify files in place. Maybe it would be better to create a new directory for each test? @moorepants @sahilshekhawat

I have no idea what appveyor does but it tests Windows whereas travis tests Linux.

@kdexd
Copy link
Author

kdexd commented Feb 4, 2016

Ok, so once your PR is merged, I will pull the code and try to complete these tests.

@oliverlee
Copy link
Contributor

You can merge the PR locally and work on your tests before it gets merged into master.

@kdexd
Copy link
Author

kdexd commented Feb 5, 2016

@oliverlee The tests will pass only if I press the enter key manually while nosetests is being executed. This is why the tests passed locally but failed on appveyor and travis, due to absence of manual intervention.

I need to provide an EOF probably.

@kdexd
Copy link
Author

kdexd commented Feb 5, 2016

Ok, so Travis CI builds are passing, but Appveyor are failing. Why so ? I can't see the reason, only show that the process exited with status 1.

@moorepants
Copy link
Member

This is the appveyor line that sow failure:

pydy.viz.tests.test_server.TestServer.test_run_server ... Command exited with code 1

Appveyor runs the code on windows. You have to make sure to use cross platform python commands, e.g. not os.system() or other things like that.

@kdexd
Copy link
Author

kdexd commented Feb 6, 2016

It isn't actually showing the exact error, I do not have Windows distro on my laptop, only Ubuntu. Though i suspect it is os.chdir that might be troubling.

@moorepants
Copy link
Member

os.chdir should work on Windows. There are a few Python commands that have trouble on Windows, for example shutil.rmtree.

@yashu-seth
Copy link
Contributor

@karandesai-96 Have you ensured that the changes are consistent with pep8? I remember I got the same error and got rid of it only after fixing pep8 issues.

@moorepants
Copy link
Member

The minimal pep8 checks we have only run on the Travis system, not appveyor.

@yashu-seth
Copy link
Contributor

Ok. Thanks.

@kdexd kdexd mentioned this pull request Feb 11, 2016
@moorepants
Copy link
Member

FYI, #326 has been merged. Maybe that will help. @oliverlee said that you can't check this on appveyor though, due to some limitation. Maybe we should only have the test that sends the kill signal run on local machines.

@kdexd
Copy link
Author

kdexd commented Mar 9, 2016

Sounds like a plan 😄

@kdexd kdexd closed this Jul 27, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants