Repository: getmoto/moto

Issue:
Incorect response when calling glue.get_table_versions
## Reporting Bugs

The current implementation of glue.get_table_versions, see [here](https://github.com/getmoto/moto/blob/78840fd71c365bb40214f59a9d7c5f5f3d00b850/moto/glue/responses.py#L73-L85)

it's different from the actual response from boto3. Specifically `VersionId` it's a key of Table, and not a separate Key.
Also UpdateTime seems missing...
A possibility is to do something like that:


```python
return json.dumps(
      {
          "TableVersions": [
            {"Table": {**table.as_dict(version=n), **{"VersionId": str(n + 1), "UpdateTime": ....random time}}
             for n in range(len(table.versions))
                ]
            }
        )
```



Discussion:
Hey @nicor88, thanks for raising this. The `VersionId` should actually be returned twice, according to the AWS docs: once as part of the key of Table, and one separate. :confused: 

Marking it as a bug.
@bblommers ah I see, as mentioned above also UpdateTime seems missing. 

Patch:
diff --git a/moto/glue/models.py b/moto/glue/models.py
--- a/moto/glue/models.py
+++ b/moto/glue/models.py
@@ -130,7 +130,7 @@ def create_table(self, database_name, table_name, table_input):
         database.tables[table_name] = table
         return table
 
-    def get_table(self, database_name, table_name):
+    def get_table(self, database_name: str, table_name: str) -> "FakeTable":
         database = self.get_database(database_name)
         try:
             return database.tables[table_name]
@@ -165,6 +165,10 @@ def delete_table(self, database_name, table_name):
             raise TableNotFoundException(table_name)
         return {}
 
+    def update_table(self, database_name, table_name: str, table_input) -> None:
+        table = self.get_table(database_name, table_name)
+        table.update(table_input)
+
     def get_partitions(self, database_name, table_name, expression):
         """
         See https://docs.aws.amazon.com/glue/latest/webapi/API_GetPartitions.html
@@ -769,16 +773,17 @@ def as_dict(self):
 
 
 class FakeTable(BaseModel):
-    def __init__(self, database_name, table_name, table_input):
+    def __init__(self, database_name: str, table_name: str, table_input):
         self.database_name = database_name
         self.name = table_name
         self.partitions = OrderedDict()
         self.created_time = datetime.utcnow()
-        self.versions = []
-        self.update(table_input)
+        self.updated_time = None
+        self.versions = [table_input]
 
     def update(self, table_input):
         self.versions.append(table_input)
+        self.updated_time = datetime.utcnow()
 
     def get_version(self, ver):
         try:
@@ -798,8 +803,12 @@ def as_dict(self, version=-1):
             "DatabaseName": self.database_name,
             "Name": self.name,
             "CreateTime": unix_time(self.created_time),
+            **self.get_version(version),
+            # Add VersionId after we get the version-details, just to make sure that it's a valid version (int)
+            "VersionId": str(int(version) + 1),
         }
-        obj.update(self.get_version(version))
+        if self.updated_time is not None:
+            obj["UpdateTime"] = unix_time(self.updated_time)
         return obj
 
     def create_partition(self, partiton_input):
diff --git a/moto/glue/responses.py b/moto/glue/responses.py
--- a/moto/glue/responses.py
+++ b/moto/glue/responses.py
@@ -66,8 +66,7 @@ def update_table(self):
         database_name = self.parameters.get("DatabaseName")
         table_input = self.parameters.get("TableInput")
         table_name = table_input.get("Name")
-        table = self.glue_backend.get_table(database_name, table_name)
-        table.update(table_input)
+        self.glue_backend.update_table(database_name, table_name, table_input)
         return ""
 
     def get_table_versions(self):


Test patch:
diff --git a/tests/test_glue/test_datacatalog.py b/tests/test_glue/test_datacatalog.py
--- a/tests/test_glue/test_datacatalog.py
+++ b/tests/test_glue/test_datacatalog.py
@@ -339,11 +339,13 @@ def test_get_table_versions():
     for n, ver in enumerate(vers):
         n = str(n + 1)
         ver["VersionId"].should.equal(n)
+        ver["Table"]["VersionId"].should.equal(n)
         ver["Table"]["Name"].should.equal(table_name)
         ver["Table"]["StorageDescriptor"].should.equal(
             version_inputs[n]["StorageDescriptor"]
         )
         ver["Table"]["PartitionKeys"].should.equal(version_inputs[n]["PartitionKeys"])
+        ver["Table"].should.have.key("UpdateTime")
 
     response = helpers.get_table_version(client, database_name, table_name, "3")
     ver = response["TableVersion"]