blob: 22e91d0a27426b5b27e823c9348fa9b253fd7988 [file] [log] [blame]
Girtsdba6ab22010-10-11 15:53:52 -07001#!/usr/bin/python
2
3# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Regression tests for devserver."""
8
9import os
10import signal
11import shutil
12import subprocess
13import sys
14import time
15import unittest
16import urllib2
17from xml.dom import minidom
18
19# Paths are relative to this script's base directory.
20STATIC_DIR = 'static'
Zdenek Behan5d21a2a2011-02-12 02:06:01 +010021TEST_IMAGE_PATH = 'testdata/devserver'
22TEST_IMAGE_NAME = 'developer-test.gz'
23TEST_IMAGE = TEST_IMAGE_PATH + '/' + TEST_IMAGE_NAME
Girtsdba6ab22010-10-11 15:53:52 -070024TEST_FACTORY_CONFIG = 'testdata/devserver/miniomaha-test.conf'
Zdenek Behan5d21a2a2011-02-12 02:06:01 +010025TEST_DATA_PATH = '/tmp/devserver-test'
Girtsdba6ab22010-10-11 15:53:52 -070026
27# TODO(girts): Get a copy of a recent request. For now, I copied this from
28# update_test.
29UPDATE_REQUEST = """<?xml version="1.0" encoding="UTF-8"?>
30<o:gupdate
31 xmlns:o="http://www.google.com/update2/request"
32 version="MementoSoftwareUpdate-0.1.0.0"
33 protocol="2.0"
34 machineid="{1B0A13AC-7004-638C-3CA6-EC082E8F5DE9}"
35 ismachine="0"
36 userid="{bogus}">
37<o:os version="Memento"
38 platform="memento"
39 sp="ForcedUpdate_i686">
40</o:os>
41<o:app appid="{87efface-864d-49a5-9bb3-4b050a7c227a}"
42 version="ForcedUpdate"
43 lang="en-us"
44 brand="GGLG"
45 track="developer-build"
46 board="x86-generic">
47<o:ping active="0"></o:ping>
48<o:updatecheck></o:updatecheck>
49</o:app>
50</o:gupdate>
51"""
52# TODO(girts): use a random available port.
53UPDATE_URL = 'http://127.0.0.1:8080/update'
54
Zdenek Behan1347a312011-02-10 03:59:17 +010055# Run all tests while being in /
56base_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
57os.chdir("/")
Girtsdba6ab22010-10-11 15:53:52 -070058
59class DevserverTest(unittest.TestCase):
60 """Regressions tests for devserver."""
61
62 def setUp(self):
63 """Copies in testing files."""
Girtsdba6ab22010-10-11 15:53:52 -070064
65 # Copy in developer-test.gz, as "static/" directory is hardcoded, and it
66 # would be very hard to change it (static file serving is handled deep
67 # inside webpy).
Zdenek Behan5d21a2a2011-02-12 02:06:01 +010068 self.image_src = os.path.join(base_dir, TEST_IMAGE)
69 self.image = os.path.join(base_dir, STATIC_DIR, TEST_IMAGE_NAME)
Girtsdba6ab22010-10-11 15:53:52 -070070 if os.path.exists(self.image):
71 os.unlink(self.image)
Zdenek Behan5d21a2a2011-02-12 02:06:01 +010072 shutil.copy(self.image_src, self.image)
Girtsdba6ab22010-10-11 15:53:52 -070073
74 self.factory_config = os.path.join(base_dir, TEST_FACTORY_CONFIG)
75
76 def tearDown(self):
77 """Removes testing files."""
78 if os.path.exists(self.image):
79 os.unlink(self.image)
80
81 def testValidateFactoryConfig(self):
82 """Tests --validate_factory_config."""
83 cmd = [
84 'python',
Zdenek Behan1347a312011-02-10 03:59:17 +010085 os.path.join(base_dir, 'devserver.py'),
Girtsdba6ab22010-10-11 15:53:52 -070086 '--validate_factory_config',
87 '--factory_config', self.factory_config,
88 ]
89 process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
90 stdout, _ = process.communicate()
91 self.assertEqual(0, process.returncode)
92 self.assertTrue('Config file looks good.' in stdout)
93
Zdenek Behan5d21a2a2011-02-12 02:06:01 +010094 def _StartServer(self, data_dir=''):
Girtsdba6ab22010-10-11 15:53:52 -070095 """Starts devserver, returns process."""
96 cmd = [
97 'python',
Zdenek Behan1347a312011-02-10 03:59:17 +010098 os.path.join(base_dir, 'devserver.py'),
Girtsdba6ab22010-10-11 15:53:52 -070099 'devserver.py',
100 '--factory_config', self.factory_config,
101 ]
Zdenek Behan5d21a2a2011-02-12 02:06:01 +0100102 if data_dir:
103 cmd.append('--data_dir')
104 cmd.append(data_dir)
Girtsdba6ab22010-10-11 15:53:52 -0700105 process = subprocess.Popen(cmd)
106 return process.pid
107
108 def testHandleUpdate(self):
109 """Tests running the server and getting an update."""
110 pid = self._StartServer()
111 try:
112 # Wait for the server to start up.
113 time.sleep(1)
114 request = urllib2.Request(UPDATE_URL, UPDATE_REQUEST)
115 connection = urllib2.urlopen(request)
116 response = connection.read()
Zdenek Behan5d21a2a2011-02-12 02:06:01 +0100117 connection.close()
Girtsdba6ab22010-10-11 15:53:52 -0700118 self.assertNotEqual('', response)
119
120 # Parse the response and check if it contains the right result.
121 dom = minidom.parseString(response)
122 update = dom.getElementsByTagName('updatecheck')[0]
123
124 codebase = update.getAttribute('codebase')
Zdenek Behan5d21a2a2011-02-12 02:06:01 +0100125 self.assertEqual('http://127.0.0.1:8080/static/' + TEST_IMAGE_NAME,
Girtsdba6ab22010-10-11 15:53:52 -0700126 codebase)
127
128 hash_value = update.getAttribute('hash')
129 self.assertEqual('kGcOinJ0vA8vdYX53FN0F5BdwfY=', hash_value)
130
131 # Try to fetch the image.
132 connection = urllib2.urlopen(codebase)
133 contents = connection.read()
Zdenek Behan5d21a2a2011-02-12 02:06:01 +0100134 connection.close()
Girtsdba6ab22010-10-11 15:53:52 -0700135 self.assertEqual('Developers, developers, developers!\n', contents)
136 finally:
137 os.kill(pid, signal.SIGKILL)
138
Zdenek Behan5d21a2a2011-02-12 02:06:01 +0100139 def testHandleDatadirUpdate(self):
140 """Tests getting an update from a specified datadir"""
141 # Push the image to the expected path where devserver picks it up.
142 image_path = os.path.join(TEST_DATA_PATH, STATIC_DIR)
143 if not os.path.exists(image_path):
144 os.makedirs(image_path)
145
146 foreign_image = os.path.join(image_path, TEST_IMAGE_NAME)
147 if os.path.exists(foreign_image):
148 os.unlink(foreign_image)
149 shutil.copy(self.image_src, foreign_image)
150
151 pid = self._StartServer(data_dir=TEST_DATA_PATH)
152 try:
153 # Wait for the server to start up.
154 time.sleep(1)
155
156 request = urllib2.Request(UPDATE_URL, UPDATE_REQUEST)
157 connection = urllib2.urlopen(request)
158 response = connection.read()
159 connection.close()
160 self.assertNotEqual('', response)
161
162 # Parse the response and check if it contains the right result.
163 dom = minidom.parseString(response)
164 update = dom.getElementsByTagName('updatecheck')[0]
165
166 codebase = update.getAttribute('codebase')
167 self.assertEqual('http://127.0.0.1:8080/static/' + TEST_IMAGE_NAME,
168 codebase)
169
170 hash_value = update.getAttribute('hash')
171 self.assertEqual('kGcOinJ0vA8vdYX53FN0F5BdwfY=', hash_value)
172
173 # Try to fetch the image.
174 connection = urllib2.urlopen(codebase)
175 contents = connection.read()
176 connection.close()
177 self.assertEqual('Developers, developers, developers!\n', contents)
178 os.unlink(foreign_image)
179 finally:
180 os.kill(pid, signal.SIGKILL)
181
Girtsdba6ab22010-10-11 15:53:52 -0700182
183if __name__ == '__main__':
184 unittest.main()