-
Notifications
You must be signed in to change notification settings - Fork 373
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
Agent status scenario #2875
Agent status scenario #2875
Changes from 25 commits
da72c37
59dbd22
633a826
14a743f
54ea0f3
e79c4c5
498b612
1e269f4
7b49e76
0a426cc
17fbf6a
995cbb9
eaadc83
fb03e07
6a8e0d6
b4951c8
c6d9300
f650fe4
a10bdfa
d6624d0
af0ec80
f1684ad
684d705
4985805
2505f69
84f207e
08778ee
75b37a8
78e9026
85c2878
324fc3c
37f548f
808f3ae
64b2bea
5adcb61
fa977e9
44d819a
a6255f8
fac1779
919b9c7
35fd0c3
72ac70a
06ca0ae
a806360
c96edba
baa9798
63c73cc
ae708e5
7da72e1
9c8a733
fc673e7
e2b3b3c
2e1f887
fc394af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# | ||
# This scenario validates the agent status is updated without any other goal state changes | ||
# | ||
name: "AgentStatus" | ||
tests: | ||
- "agent_status/agent_status.py" | ||
images: | ||
- "endorsed" | ||
- "endorsed-arm64" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
#!/usr/bin/env python3 | ||
import datetime | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's move those imports below, with the rest of them |
||
from time import sleep | ||
|
||
from assertpy import assert_that | ||
# Microsoft Azure Linux Agent | ||
# | ||
# Copyright 2018 Microsoft Corporation | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
# | ||
# Validates the agent status is updated without any other goal state changes | ||
# | ||
|
||
from azure.mgmt.compute.models import VirtualMachineInstanceView | ||
|
||
from tests_e2e.tests.lib.agent_test import AgentTest | ||
from tests_e2e.tests.lib.agent_test_context import AgentTestContext | ||
from tests_e2e.tests.lib.logging import log | ||
from tests_e2e.tests.lib.ssh_client import SshClient | ||
from tests_e2e.tests.lib.virtual_machine_client import VirtualMachineClient | ||
|
||
|
||
def validate_instance_view_vmagent_status(instance_view: VirtualMachineInstanceView): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why use global functions? shouldn't these be methods of the test class? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pycharm suggested making them functions since they were static There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think they should be methods of the test class though, I'll move them in the test class |
||
is_valid = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all those checks should probably raise exceptions on failure, that would simplify the code since there is no need for the valid flag and would also allow you include the actual error in the main assert of the test (see comment below) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
status = instance_view.vm_agent.statuses[0] | ||
|
||
# Validate message field | ||
message = status.message | ||
if message is None: | ||
is_valid = False | ||
log.info("Instance view is missing an agent status message, waiting to retry...") | ||
elif 'unresponsive' in message: | ||
is_valid = False | ||
log.info("Instance view shows unresponsive agent, waiting to retry...") | ||
|
||
# Validate display status field | ||
display_status = status.display_status | ||
if display_status is None: | ||
is_valid = False | ||
log.info("Instance view is missing an agent display status, waiting to retry...") | ||
elif 'Not Ready' in display_status: | ||
is_valid = False | ||
log.info("Instance view shows agent status is not ready, waiting to retry...") | ||
|
||
return is_valid | ||
|
||
|
||
def validate_instance_view_vmagent(instance_view: VirtualMachineInstanceView): | ||
is_valid = True | ||
|
||
# Validate vm_agent_version field | ||
vm_agent_version = instance_view.vm_agent.vm_agent_version | ||
if vm_agent_version is None: | ||
is_valid = False | ||
log.info("Instance view is missing agent version, waiting to retry...") | ||
elif 'Unknown' in vm_agent_version: | ||
is_valid = False | ||
log.info("Instance view shows agent version is unknown, waiting to retry...") | ||
|
||
# Validate statuses field | ||
statuses = instance_view.vm_agent.statuses | ||
if statuses is None: | ||
is_valid = False | ||
log.info("Instance view is missing agent statuses, waiting to retry...") | ||
elif len(statuses) < 1: | ||
is_valid = False | ||
log.info("Instance view is missing an agent status entry, waiting to retry...") | ||
else: | ||
is_valid = validate_instance_view_vmagent_status(instance_view=instance_view) | ||
|
||
return is_valid | ||
|
||
|
||
def validate_instance_view(instance_view: VirtualMachineInstanceView): | ||
instance_view_is_valid = True | ||
|
||
if instance_view.vm_agent is None: | ||
instance_view_is_valid = False | ||
log.info("Instance view is missing vm agent, waiting to retry...") | ||
else: | ||
instance_view_is_valid = validate_instance_view_vmagent(instance_view=instance_view) | ||
|
||
if instance_view.statuses is None: | ||
instance_view_is_valid = False | ||
log.info("Instance view is missing statuses, waiting to retry...") | ||
|
||
if instance_view_is_valid: | ||
log.info("Instance view is valid, agent version: {0}, status: {1}" | ||
.format(instance_view.vm_agent.vm_agent_version, | ||
instance_view.vm_agent.statuses[0].display_status)) | ||
|
||
return instance_view_is_valid | ||
|
||
|
||
class AgentStatus(AgentTest): | ||
def __init__(self, context: AgentTestContext): | ||
super().__init__(context) | ||
self._ssh_client = SshClient( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do have method in AgentTestContext, reusing that self._context.create_ssh_client() simplifies things. |
||
ip_address=self._context.vm_ip_address, | ||
username=self._context.username, | ||
private_key_file=self._context.private_key_file) | ||
|
||
def run(self): | ||
log.info("") | ||
log.info("*******Verifying the agent status*******") | ||
|
||
vm = VirtualMachineClient(self._context.vm) | ||
|
||
timeout = datetime.datetime.now() + datetime.timedelta(minutes=5) | ||
instance_view_is_valid = False | ||
|
||
# Retry validating instance view with timeout of 5 minutes | ||
while datetime.datetime.now() < timeout and not instance_view_is_valid: | ||
instance_view = vm.get_instance_view() | ||
log.info("") | ||
log.info("Validating VM Instance View...") | ||
log.info("Instance view of VM is:\n%s", instance_view.serialize()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you pretty-print the serialization? |
||
|
||
instance_view_is_valid = validate_instance_view(instance_view) | ||
if not instance_view_is_valid: | ||
log.info("") | ||
log.info("Instance view is not valid, waiting 10s before retry...") | ||
sleep(10) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sleep 10 secs with timeout 5 mins is too aggressive retries. I don't think too frequent reties needed here as we decide to wait for 5 mins. |
||
|
||
log.info("") | ||
assert_that(instance_view_is_valid).described_as("Timeout has expired, instance view is not valid.").is_true() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the error message should include why the view is not valid |
||
|
||
|
||
if __name__ == "__main__": | ||
AgentStatus.run_from_command_line() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"any", rather than "any other"