autoupdate.py: Allow max_updates through update URL

Currently in order to put a ceiling on the number of updates that can be
performed in a devserver, we need to spawn a new devserver with flag
--max_updates. The problem is now for each run of an autotest, they
should spwan a new devserver alongside the lab devservers which is not
ideal.

We solve this problem by dynamically configuring the devserver
using a unique identifier. This is done by calling into 'session_id' API
of the devserver. Then clients can send their requests appending this
session_id to be responded likewise.

For maximum updates, we first configure the devserver to set a
'max_updates' data for a unique session ID. Then client can send
requests using the session ID as a query string be capped on the number
of updates they get.

BUG=chromium:1004489
TEST=autoupdate_unittest.py
TEST=devserver_integration_test.py

Change-Id: Ieef921b177ba0ec789d6471a34a4f8e44f5482af
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/1996148
Tested-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Allen Li <ayatane@chromium.org>
diff --git a/devserver.py b/devserver.py
index 6230f8c..a0919a9 100755
--- a/devserver.py
+++ b/devserver.py
@@ -1499,9 +1499,29 @@
     label = '/'.join(args)
     body_length = int(cherrypy.request.headers.get('Content-Length', 0))
     data = cherrypy.request.rfile.read(body_length)
-
     return updater.HandleUpdatePing(data, label, **kwargs)
 
+  @cherrypy.expose
+  def session(self, *args):
+    """Adds a new Session for a unique session ID with POST body as data.
+
+    Calling this API establishes a configuration by keeping a piece of data (in
+    JSON format) for this specific session ID. Users can later send requests to
+    devserver identifying this session ID to have different responses. The
+    session ID is a unique identifier string (can be in any format)
+
+    To use, call this API like:
+    curl -X POST -d '{"foo": "bar"}' \
+        http://127.0.0.1:8080/session/some-random-string
+
+    The users of this API will send the session ID as a query string with any
+    other parameters they like:
+
+    curl http://127.0.0.1:8080/some-api?session=some-random-string
+    """
+    content_length = int(cherrypy.request.headers.get('Content-Length', 0))
+    content = cherrypy.request.rfile.read(content_length)
+    return updater.SetSessionData(args[0], json.loads(content))
 
 def _CleanCache(cache_dir, wipe):
   """Wipes any excess cached items in the cache_dir.
@@ -1537,6 +1557,7 @@
   group.add_option('--host_log',
                    action='store_true', default=False,
                    help='record history of host update events (/api/hostlog)')
+  # TODO(crbug/1004489): Deperecate max_updates.
   group.add_option('--max_updates',
                    metavar='NUM', default=-1, type='int',
                    help='maximum number of update checks handled positively '