Skip to content
This repository was archived by the owner on Sep 16, 2020. It is now read-only.

Rover self register#91

Merged
hbradio merged 23 commits intodevelopmentfrom
feature/Rover_self_register
Mar 6, 2017
Merged

Rover self register#91
hbradio merged 23 commits intodevelopmentfrom
feature/Rover_self_register

Conversation

@hbradio
Copy link
Copy Markdown
Collaborator

@hbradio hbradio commented Feb 24, 2017

Makes rover periodically check in with rovercode-web.

Also, fixes test coverage when in Docker.

@hbradio hbradio requested a review from cabarnes February 24, 2017 16:19
@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-27.3%) to 43.5% when pulling 82daf61 on feature/Rover_self_register into 5c76555 on development.

www/app.py Outdated
print "rovercode-web id is " + str(web_id)
return r

def heartbeat_thread():
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm open to ideas about how to unit test this function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See below.

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-27.3%) to 43.5% when pulling c705b6f on feature/Rover_self_register into eaf939d on development.

README.md Outdated
$ py.test
```
We're having some trouble running pytest-cov inside the Docker container. If you are using Docker for development and want to run test, you'll need to `pip install pytest pytest-cov` outside and run the `py.test` outside of Docker for now.
Or, if your using Docker, make sure the container is running (the `sudo docker run ...` command above), then do:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you're

www/app.py Outdated
def register_with_web():
global web_id
global payload
payload = {'name': 'Chipy', 'owner': 'Mr. Hurlburt', 'local_ip': get_local_ip()}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The name and owner will eventually come from some kind of configuration?

www/app.py Outdated
global payload
payload = {'name': 'Chipy', 'owner': 'Mr. Hurlburt', 'local_ip': get_local_ip()}
print "Registering with rovercode-web"
r = requests.post("https://rovercode.com/mission-control/rovers/", payload)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would suggest moving the base URL somewhere that can be accessed by everything needing it so you only will have to change it in one place in the future.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call. Will do.

def test_sensor_init():
assert len(app.binary_sensors) > 0

def test_get_local_ip():
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To test all of these effectively, you'll need to use something like responses. It's a way to mock up the response from the server so that you don't actually need a server for the tests. Then you can check through all of the error cases as well. I can help you with it at some point if you run into issues. Basically, you setup a response to a particular request and see how the function behaves.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, I'll try it out!
The other challenge with heartbeat_thread is that it is an infinite loop. Any ideas on how to get around that problem?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you'll need a way to exit the loop. A shutdown variable or something like it that it's checking every time through the loop. If it were part of a class, you could have a class method to start and stop the thread. I'm not sure if the socketio background task will accept a class member or not.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I wrapped it in a class with a stop function that disabled the shutdown variable. And socketio has not problem accepting a class member.

But, in my test function, how do I get the result of the thread function? If I start it in the background using socketio, I don't know where the return goes to. If I start it in the foreground, it blocks and I can't call the .stopThread function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe a better way is to add an optional parameter (run_once) that is false by default, but that the test can set to true so that it just runs through once. That won't give 100% test coverage, but it will test most of it. I think you'd have to spin up a task in your test in order to stop the task in the infinite loop case.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good -- I'll go with the run_once strategy for now.

www/app.py Outdated
print "rovercode-web id is " + str(web_id)
return r

def heartbeat_thread():
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See below.

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-12.7%) to 58.011% when pulling c5f0144 on feature/Rover_self_register into eaf939d on development.

@hbradio
Copy link
Copy Markdown
Collaborator Author

hbradio commented Mar 4, 2017

Also added prospector and fixed the lint warning.

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-12.7%) to 58.011% when pulling c5f0144 on feature/Rover_self_register into eaf939d on development.

.travis.yml Outdated
- pip install coveralls
script:
- py.test
- pwd && prospector
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you still need to print the directory here or was that for debugging?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Nope, I'll remove it!

www/app.py Outdated
print "Registering rover!"
ws_thread = None
hb_thread = None
payload = None;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Stray ;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Whoops, will fix

json=response_payload, status=200,
content_type='application/json')
result = heartbeat_manager.register()
assert result.status_code in [200, 201]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You set the response to 200 so you should assert that it is exactly 200.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point. Will change.

web_id = 333
heartbeat_manager = app.HeartBeatManager(payload=payload)
response_payload = payload.copy()
response_payload['id'] = 333
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can use the web_id variable here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, will do.

www/app.py Outdated
payload = None;

pwm = pwmLib.get_platform_pwm(pwmtype="softpwm")
gpio = gpioLib.get_platform_gpio();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Stray ;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Whoops, will fix all of these.

www/app.py Outdated
self.run = True;
self.thread = None;
self.web_id = id;
self.payload = payload;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Stray ; for each of these

content_type='application/json')

result = heartbeat_manager.thread_func(run_once=True)
assert result.status_code in [200, 201]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Only 200

assert len(responses.calls) == 1
assert responses.calls[0].request.url == app.ROVERCODE_WEB_REG_URL+str(web_id)+"/"

# Test for a rover who has been forgotten by the server
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be a separate test

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point. I'll separate it out.


heartbeat_manager.web_id = web_id_new
result = heartbeat_manager.thread_func(run_once=True)
assert result.status_code in [200, 201]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Only 200

@cabarnes
Copy link
Copy Markdown
Member

cabarnes commented Mar 5, 2017

Looks like most of the missing test coverage is in the API handlers for the stored block diagrams. All of that will be going away since they will be stored in the cloud right?

@cabarnes
Copy link
Copy Markdown
Member

cabarnes commented Mar 5, 2017

If you hadn't already found it, there's a visual representation of the test coverage output in htmlcov/index.html.

@hbradio
Copy link
Copy Markdown
Collaborator Author

hbradio commented Mar 5, 2017

I hadn't found the visual representation. That's awesome.

@hbradio
Copy link
Copy Markdown
Collaborator Author

hbradio commented Mar 5, 2017

Agreed -- a lot of the uncovered code deals with saving block diagrams. We can delete that stuff. Maybe in a separate PR?

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-12.7%) to 58.011% when pulling 84c5dd6 on feature/Rover_self_register into eaf939d on development.

@cabarnes
Copy link
Copy Markdown
Member

cabarnes commented Mar 5, 2017

Separate PR is fine with me. There is one missing change for asserting 200 from my comments above and then I can approve.

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage decreased (-12.7%) to 58.011% when pulling 8050e90 on feature/Rover_self_register into eaf939d on development.

@hbradio hbradio merged commit 72b90b2 into development Mar 6, 2017
@hbradio hbradio deleted the feature/Rover_self_register branch March 6, 2017 20:26
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants