devserver.py: Handle query strings for critical updates

Currently, the only way for devserver to return a response indicating a
critical update is to spawn it with '--critical_update' flag. This is
not an ideal implementation as the autotests that require a critical
update response will need to spawn a new devserver (probably along with
the lab devservers) to achieve this. A much easier approach is to pass
"critical_update=True" query string to the update URL passed to the
update_engine. This way the devserver/nebraska would know that response
to this specific request should be critical.

BUG=chromium:1004487
TEST=devserver_integration_test.py
TEST=manually started devserver.py and send a request to this URL:
http://127.0.0.1:8080/update/?critical_update=True

Change-Id: Ie9908ce7ae83d5ec29534b1e2cba6e60bf242dbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/1996147
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Tested-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: David Haddock <dhaddock@chromium.org>
diff --git a/devserver_integration_test.py b/devserver_integration_test.py
index fbd20b4..fbde817 100755
--- a/devserver_integration_test.py
+++ b/devserver_integration_test.py
@@ -29,6 +29,8 @@
 
 from xml.dom import minidom
 
+import requests
+
 from six.moves import urllib
 
 import psutil  # pylint: disable=import-error
@@ -235,8 +237,10 @@
     """
     update_label = '/'.join([UPDATE, label])
     response = self._MakeRPC(
-        update_label, data=UPDATE_REQUEST.substitute({'appid': appid}))
+        update_label, data=UPDATE_REQUEST.substitute({'appid': appid}),
+        critical_update=True)
     self.assertNotEqual('', response)
+    self.assertIn('deadline="now"', response)
 
     # Parse the response and check if it contains the right result.
     dom = minidom.parseString(response)
@@ -286,19 +290,12 @@
     request = '/'.join([self.devserver_url, rpc])
     if kwargs:
       # Join the kwargs to the URL.
-      request += '?' + '&'.join('%s=%s' % item for item in kwargs.items())
+      request += '?' + '&'.join('%s=%s' % (k, v) for k, v in kwargs.items())
 
-    # Let's log output for all rpc's without timeouts because we only
-    # use timeouts to check to see if something is up and these checks tend
-    # to be small and so logging it will be extremely repetitive.
-    if not timeout:
-      logging.info('Making request using %s', request)
-
-    connection = urllib.request.urlopen(
-        request, data=data.encode('utf-8') if data else None, timeout=timeout)
-    output = connection.read().decode('utf-8')
-    connection.close()
-    return output
+    response = (requests.post(request, data=data, timeout=timeout) if data
+                else requests.get(request, timeout=timeout))
+    response.raise_for_status()
+    return response.text
 
 
 class AutoStartDevserverTestBase(DevserverTestBase):
@@ -552,7 +549,7 @@
     self.assertEqual(response, expected_update_url)
 
     logging.info('Now give xbuddy a bad path.')
-    self.assertRaises(urllib.error.HTTPError,
+    self.assertRaises(requests.exceptions.RequestException,
                       self._MakeRPC,
                       '/'.join([XBUDDY, xbuddy_bad_path]))
 
@@ -583,6 +580,4 @@
 
 
 if __name__ == '__main__':
-  logging_format = '%(levelname)-8s: %(message)s'
-  logging.basicConfig(level=logging.DEBUG, format=logging_format)
   unittest.main()