util: More doc for the Gerrit bot, add padding time to query age
authorHoa Nguyen <hoanguyen@ucdavis.edu>
Tue, 1 Dec 2020 05:11:12 +0000 (21:11 -0800)
committerHoa Nguyen <hoanguyen@ucdavis.edu>
Tue, 8 Dec 2020 07:32:26 +0000 (07:32 +0000)
The following changes were made:
- Improve the wording of comments in the Python files and of the
documentation in the README file.
- Add 10 seconds to the query age so that the bot wouldn't miss
any new changes that could be missed due to time difference between
the Gerrit server and the bot.

Change-Id: Ic75f9572653a248230a8b4b0bd360a8d22efd371
Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38155
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
util/gerrit-bot/README.md
util/gerrit-bot/bot.py [changed mode: 0644->0755]

index df1b62b4c79e74eb20ae4780e8503ec174ddf855..19eb26a8ab757f000008e3947fbf083be594c479 100644 (file)
@@ -1,20 +1,25 @@
 ## Gerrit Bot
 
 ### Getting Username and Password
+Gerrit REST API uses the account username and password for the authentication
+purpose. They are necessary to make a request.
+
+The following are steps to obtain the username and password from `.gitcookies`
+files,
 
 * Follow this link
 [https://gem5-review.googlesource.com/new-password](https://gem5-review.googlesource.com/new-password)
-and copy the authenticating script to a file, supposedly `gerrit_auth_script`.
+and copy the authenticating script to a new file.
 
 * After that, run the `extract_gitcookies.py` to extract the username and
-password from the obtained script.
+password from the authenticating script.
 For example, the following command extracts the username and password from
-`gerrit_auth_script` and writes them to `GEM5_BOT_AUTH_INFO`,
+`gerrit_auth_script` and writes them to `.data/auth`,
 ```sh
-python3 extract_gitcookies.py gerrit_auth_script GEM5_BOT_AUTH_INFO
+python3 extract_gitcookies.py gerrit_auth_script .data/auth
 ```
-The `GEM5_BOT_AUTH_INFO` will have two lines: the first line contains the
-username and the second line is the corresponding password.
+The `.data/auth` will have two lines: the first line contains the username and
+the second line is the corresponding password.
 **Notes:**
 * The above link, [https://gem5-review.googlesource.com/new-password](https://gem5-review.googlesource.com/new-password),
 generates a new pair of username and password per visit.
@@ -23,35 +28,44 @@ file. For example, `python3 extract_gitcookies.py ~/.gitcookies output`
 will write all pairs of username and password in two lines per pair to
 `output`.
 * The gerrit-bot only reads the pair of username and password appearing
-in the first and the second line in the `GEM5_BOT_AUTH_INFO` file.
+in the first and the second line in the `.data/auth` file.
 
 ### Gerrit Bot
 
-**Notes:** this is likely to be changed.
-
-The idea of implementing the bot is as follows,
-* The `Configs` class should contain all constants that are configurable
-prior to running.
-* Classes such as `LabelInfo` and `ReviewInput` are simplied versions
-resembling those data structures of the same name according to the
-[Gerrit REST API documentation](https://gerrit-review.googlesource.com/Documentation/rest-api.html#_endpoints).
-* In the class `GerritRestAPIRequester`,
-    * The `__generate_*_request()` functions should be a one-to-one function
-to a set of Gerrit REST API endpoints. The functions should generate a
-`requests.Request` object.
-    * The `send_*()` functions are adapted to a more specific use case.
+The structure of the Gerrit bot is as follows:
+* The `GerritBotConfig` class should contain all constants that are
+configurable prior to running.
 
 ### Gerrit API
 * Query options: [https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#query-options](https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#query-options)
 
-### Appendix I. `extract_gitcookies.py`
-This script extracts all pairs of username and password from the gerrit
-authentication script from a file or a .gitcookies file.
+### Deployment
+The Gerrit bot is intended to be run as a cron job.
+Each run of the Gerrit bot will query new changes made to the Gerrit server
+within a certain period of time, perform actions on each change, and exit.
+
+The following are steps to deploy the Gerrit bot:
+
+* Create `.data` folder in the same folder as `bot.py`,
+```sh
+mkdir .data
+```
+
+* Follow the steps [here](#getting-username-and-password) to get the Gerrit
+bot account username and password.
+
+* To run the Gerrit bot once,
+```sh
+./bot.py
+```
 
-The usage of the script is as follows,
+* To edit the cron table,
 ```sh
-python3 extract_gitcookies.py input_path output_path
+crontab -e
 ```
 
-### Appendix II. `MAINTAINERS.json`
-This file should be consistent with the file `MAINTAINERS`.
+To run the Gerrit bot every 30 minutes, add the following line to the
+crontable,
+```python
+*/1 * * * * cd /path/to/gerrit/bot/directory && ./bot.py
+```
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index f63008f..70be95d
@@ -43,12 +43,22 @@ class GerritBotConfig:
     @staticmethod
     def DefaultConfig():
         default_config = GerritBotConfig()
+
+        # path to the file containing the username and password of the
+        # Gerrit bot
         default_config.auth_file_path = ".data/auth"
+
+        # path to the file containing the previous time a query to Gerrit
+        # REST API was made
         default_config.time_tracker_file_path = ".data/prev_query_time"
-        # query changes made within 2 days if not specified
+
+        # query changes made within 2 days if prev_query_time is not specified
         default_config.default_query_age = "2d"
-        default_config.maintainers_file_path = None # the maintainers library
-                                                    # will figure the path out
+
+        # path to the maintainers file
+        # if it is `None`, the maintainers library will figure that out
+        default_config.maintainers_file_path = None
+
         default_config.api_entry_point = "https://gem5-review.googlesource.com"
         default_config.projects_prefix = "public/gem5"
         default_config.query_limit = 1000 # at most 1000 new changes per query
@@ -95,8 +105,7 @@ class GerritBot:
 
         return prev_query_time
 
-    def __update_time_tracker_file(self, file_path):
-        prev_query_time = time.time()
+    def __update_time_tracker_file(self, file_path, prev_query_time):
         with open(file_path, "w") as f:
             f.write(f"{prev_query_time}\n")
             f.write(f"# The above time is the result of calling time.time() "
@@ -125,9 +134,13 @@ class GerritBot:
     def _pre_run(self):
         self.prev_query_time = \
             self.__read_time_tracker_file(self.config.time_tracker_file_path)
+        self.curr_time = time.time()
         if self.prev_query_time > 0:
+            # adding 10 seconds to the query age to make sure that
+            # we won't miss any new changes
             self.query_age = \
-              convert_time_in_seconds(int(time.time() - self.prev_query_time))
+              convert_time_in_seconds(
+                int(self.curr_time - self.prev_query_time + 10))
         else:
             self.query_age = self.config.default_query_age
 
@@ -138,7 +151,8 @@ class GerritBot:
                                       self.gerrit_api)
 
     def _post_run(self):
-        self.__update_time_tracker_file(self.config.time_tracker_file_path)
+        self.__update_time_tracker_file(self.config.time_tracker_file_path,
+                                        self.curr_time)
 
     def run(self):
         self._pre_run()