blob: 07c2b8a3a5165559fe017107090f4750feabd358 [file] [log] [blame]
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittests for responses sent by the Nebraska server."""
from __future__ import print_function
import mock
import unittest
from xml.etree import ElementTree
import nebraska
from unittest_common import AppDataGenerator
# pylint: disable=protected-access
class XMLResponseTemplates(object):
"""XML Templates for testing."""
RESPONSE_TEMPLATE_INVALID = """
invalid xml!!
<?xml version="1.0" encoding="UTF-8"?>
<response protocol="3.0" server="nebraska">
<daystart elapsed_days="" elapsed_seconds=""/>
</response>
"""
APP_TEMPLATE = """
<app appid="" status="">
</app>
"""
APP_TEMPLATE_INVALID = """
invalid xml!!
<app appid="" status="">
</app>
"""
UPDATE_CHECK_TEMPLATE_NO_PACKAGE = """
<updatecheck status="ok">
<urls>
</urls>
<manifest version="">
<actions>
<action event="update" run=""/>
<action ChromeOSVersion=""
ChromeVersion="1.0.0.0"
IsDelta=""
IsDeltaPayload=""
MaxDaysToScatter="14"
MetadataSignatureRsa=""
MetadataSize=""
event="postinstall"
sha256=""/>
</actions>
</manifest>
</updatecheck>
"""
UPDATE_CHECK_TEMPLATE_NO_URL = """
<updatecheck status="ok">
<manifest version="">
<actions>
<action event="update" run=""/>
<action ChromeOSVersion=""
ChromeVersion="1.0.0.0"
IsDelta=""
IsDeltaPayload=""
MaxDaysToScatter="14"
MetadataSignatureRsa=""
MetadataSize=""
event="postinstall"
sha256=""/>
</actions>
<packages>
<package fp="null"
hash_sha256=""
name=""
required="true"
size=""/>
</packages>
</manifest>
</updatecheck>
"""
class ResponseTest(unittest.TestCase):
"""Tests for Response class."""
def testGetXMLStringSuccess(self):
"""Tests GetXMLString success."""
app_list = [
AppDataGenerator(
appid="foo",
is_delta=True,
version="1.0.0",
src_version="0.9.0"),
AppDataGenerator(
appid="bar",
is_delta=True,
version="2.0.0",
src_version="1.9.0"),
AppDataGenerator(
appid="foobar",
is_delta=False,
version="4.0.0",
src_version=None)]
request = mock.MagicMock()
request.ParseRequest.return_value = [
nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="foo",
ping=True,
event_type="1",
event_result="1",
version="1.0.0",
delta_okay=False),
nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="bar",
ping=True,
event_type="1",
event_result="1",
version="2.0.0",
delta_okay=False),
nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="foobar",
ping=True,
event_type="1",
event_result="1",
version="4.0.0",
delta_okay=False)]
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.side_effect = app_list
response = nebraska.Response(
request, update_index, install_index, payload_addr)
response = response.GetXMLString()
response_root = ElementTree.fromstring(response)
app_responses = response_root.findall('app')
for response, app in zip(app_responses, app_list):
self.assertTrue(response.attrib['appid'] == app.appid)
self.assertTrue(response.find('ping') is not None)
self.assertTrue(response.find('event') is not None)
class AppResponseTest(unittest.TestCase):
"""Tests for AppResponse class."""
def testAppResponseUpdate(self):
"""Tests AppResponse for an update request with matching payload."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="foo",
version="1.0.0",
delta_okay=False)
match = AppDataGenerator(
appid="foo",
is_delta=False,
version="1.0.0",
src_version=None)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.return_value = match
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertFalse(response._err_not_found)
self.assertTrue(response._app_data is match)
update_index.Find.assert_called_once_with(app_request)
install_index.Find.assert_not_called()
def testAppResponseInstall(self):
"""Tests AppResponse generation for install request with match."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.INSTALL,
appid="foo",
version="1.0.0",
delta_okay=False)
match = AppDataGenerator(
appid="foo",
is_delta=False,
version="1.0.0",
src_version=None)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
install_index.Find.return_value = match
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertFalse(response._err_not_found)
self.assertTrue(response._app_data is match)
install_index.Find.assert_called_once_with(app_request)
update_index.Find.assert_not_called()
def testAppResponseNoMatch(self):
"""Tests AppResponse generation for update request with an unknown appid."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="foo",
version="1.0.0",
delta_okay=False)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.return_value = None
update_index.Contains.return_value = False
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertTrue(response._err_not_found)
self.assertTrue(response._app_data is None)
update_index.Find.assert_called_once_with(app_request)
install_index.Find.assert_not_called()
def testAppResponseNoUpdate(self):
"""Tests AppResponse generation for update request with no new versions."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.UPDATE,
appid="foo",
version="1.0.0",
delta_okay=False)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.return_value = None
update_index.Contains.return_value = True
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertFalse(response._err_not_found)
self.assertTrue(response._app_data is None)
update_index.Find.assert_called_once_with(app_request)
install_index.Find.assert_not_called()
def testAppResponsePing(self):
"""Tests AppResponse generation for no-op with a ping request."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.NO_OP,
appid="foo",
ping=True,
version="1.0.0")
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.return_value = None
update_index.Contains.return_value = True
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertFalse(response._err_not_found)
self.assertTrue(response._app_data is None)
update_index.Find.assert_not_called()
install_index.Find.assert_not_called()
def testAppResponseEvent(self):
"""Tests AppResponse generation for requests with events."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.NO_OP,
appid="foo",
event_type="1",
event_result="1",
version="1.0.0")
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
update_index.Find.return_value = None
update_index.Contains.return_value = True
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
self.assertTrue(response._app_request == app_request)
self.assertFalse(response._err_not_found)
self.assertTrue(response._app_data is None)
update_index.Find.assert_not_called()
install_index.Find.assert_not_called()
def testCompileSuccess(self):
"""Tests successful compilation of an AppData instance."""
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.INSTALL,
appid="foo",
version="1.0.0",
delta_okay=False)
match = AppDataGenerator(
appid="foo",
is_delta=False,
version="1.0.0",
src_version=None)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
install_index.Find.return_value = match
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
compiled_response = response.Compile()
url_tag = compiled_response.find('updatecheck/urls/url')
manifest_tag = compiled_response.find('updatecheck/manifest')
package_tag = compiled_response.find(
'updatecheck/manifest/packages/package')
action_tag = compiled_response.findall(
'updatecheck/manifest/actions/action')[1]
self.assertTrue(url_tag is not None)
self.assertTrue(manifest_tag is not None)
self.assertTrue(package_tag is not None)
self.assertTrue(action_tag is not None)
self.assertTrue(compiled_response.attrib['appid'] == match.appid)
self.assertTrue(url_tag.attrib['codebase'] == payload_addr + "/install/")
self.assertTrue(manifest_tag.attrib['version'] == match.version)
self.assertTrue(package_tag.attrib['hash_sha256'] == match.sha256_hash)
self.assertTrue(package_tag.attrib['fp'] == "1.%s" % match.sha256_hash)
self.assertTrue(package_tag.attrib['name'] == match.name)
self.assertTrue(package_tag.attrib['size'] == match.size)
self.assertTrue(action_tag.attrib['ChromeOSVersion'] == match.version)
self.assertTrue(action_tag.attrib['IsDeltaPayload'] == "true" if
match.is_delta else "false")
def testCompileParseInvalidXML(self):
"""Tests Compile handling of invalid XML templates."""
with mock.patch('nebraska.XMLResponseTemplates') as template_mock:
with self.assertRaises(ElementTree.ParseError):
template_mock.APP_TEMPLATE = \
XMLResponseTemplates.APP_TEMPLATE_INVALID
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.NO_OP,
appid="foo",
event_type="1",
event_result="1",
version="1.0.0")
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
response.Compile()
def testCompileParseMissingURL(self):
"""Tests Compile handling of missing tags."""
with mock.patch('nebraska.XMLResponseTemplates') as template_mock:
with self.assertRaises(AttributeError):
template_mock.APP_TEMPLATE = \
XMLResponseTemplates.APP_TEMPLATE
template_mock.UPDATE_CHECK_TEMPLATE = \
XMLResponseTemplates.UPDATE_CHECK_TEMPLATE_NO_URL
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.INSTALL,
appid="foo",
version="1.0.0",
delta_okay=False)
match = AppDataGenerator(
appid="foo",
is_delta=False,
version="1.0.0",
src_version=None)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
install_index.Find.return_value = match
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
response.Compile()
with mock.patch('nebraska.XMLResponseTemplates') as template_mock:
with self.assertRaises(AttributeError):
template_mock.APP_TEMPLATE = \
XMLResponseTemplates.APP_TEMPLATE
template_mock.UPDATE_CHECK_TEMPLATE = \
XMLResponseTemplates.UPDATE_CHECK_TEMPLATE_NO_PACKAGE
app_request = nebraska.Request.AppRequest(
request_type=nebraska.Request.AppRequest.RequestType.INSTALL,
appid="foo",
version="1.0.0",
delta_okay=False)
match = AppDataGenerator(
appid="foo",
is_delta=False,
version="1.0.0",
src_version=None)
payload_addr = "www.google.com"
update_index = mock.MagicMock()
install_index = mock.MagicMock()
install_index.Find.return_value = match
response = nebraska.Response.AppResponse(
app_request, update_index, install_index, payload_addr)
response.Compile()
if __name__ == '__main__':
unittest.main()