diff --git a/Documentation/Network-Request-Tests/CurlExeTest.py b/Documentation/Network-Request-Tests/CurlExeTest.py new file mode 100644 index 000000000..331bd4cc8 --- /dev/null +++ b/Documentation/Network-Request-Tests/CurlExeTest.py @@ -0,0 +1,33 @@ +import sys +import time +import os +import subprocess +import TestUtils +import TestKey + +if __name__ == "__main__": + sessionString = TestKey.SessionKey + + urlArray = TestUtils.buildUrlArray(sessionString) + + command = "curl.exe -Z "; + + for key, value in TestUtils.UnrealStyleHeaders.items(): + command += "--header \"" + key + ": " + value + "\" " + + command += "\"" + urlArray[0] + "\" " + command += "\"" + urlArray[1] + "\" " + command += "\"" + urlArray[2] + "\" " + command += "\"" + urlArray[3] + "\"" + + print ("\nExecuting....\n\n" + command + "\n\n") + + startMark = time.time() + + r = subprocess.run(command, capture_output=True) + + bytesDownloaded = len(r.stdout) + + secsElapsed = time.time()-startMark + + TestUtils.printSummary(secsElapsed, bytesDownloaded) diff --git a/Documentation/Network-Request-Tests/PyRequestsLibTest.py b/Documentation/Network-Request-Tests/PyRequestsLibTest.py new file mode 100644 index 000000000..7e113c480 --- /dev/null +++ b/Documentation/Network-Request-Tests/PyRequestsLibTest.py @@ -0,0 +1,49 @@ +import sys +import time +import requests +import concurrent.futures +import TestUtils +import TestKey + + +def load_url(url, session): + print("Loading URL...") + + response = session.get(url) + + global gBytesDownloaded + gBytesDownloaded += len(response.text); + + print(response.status_code) + + +if __name__ == "__main__": + global gBytesDownloaded + gBytesDownloaded = 0 + + sessionString = TestKey.SessionKey + + urlArray = TestUtils.buildUrlArray(sessionString) + + session = requests.Session() + session.headers.update(TestUtils.UnrealStyleHeaders) + + startMark = time.time() + + out = [] + CONNECTIONS = 100 + with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor: + future_to_url = (executor.submit(load_url, url, session) for url in urlArray) + for future in concurrent.futures.as_completed(future_to_url): + try: + data = future.result() + except Exception as exc: + data = str(type(exc)) + print("Exception caught: " + data) + finally: + print("request completed") + out.append(data) + + secsElapsed = time.time()-startMark + + TestUtils.printSummary(secsElapsed, gBytesDownloaded) diff --git a/Documentation/Network-Request-Tests/PyUrlLib3Test.py b/Documentation/Network-Request-Tests/PyUrlLib3Test.py new file mode 100644 index 000000000..3f29bf9b1 --- /dev/null +++ b/Documentation/Network-Request-Tests/PyUrlLib3Test.py @@ -0,0 +1,48 @@ +import sys +import time +import urllib3 +import concurrent.futures +import TestUtils +import TestKey + + +def load_url(url, http): + print("Loading URL...") + + response = http.request("GET", url) + + global gBytesDownloaded + gBytesDownloaded += len(response.data); + + print(response.status) + + +if __name__ == "__main__": + global gBytesDownloaded + gBytesDownloaded = 0 + + sessionString = TestKey.SessionKey + + urlArray = TestUtils.buildUrlArray(sessionString) + + startMark = time.time() + + http = urllib3.PoolManager(headers=TestUtils.UnrealStyleHeaders) + + out = [] + CONNECTIONS = 100 + with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor: + future_to_url = (executor.submit(load_url, url, http) for url in urlArray) + for future in concurrent.futures.as_completed(future_to_url): + try: + data = future.result() + except Exception as exc: + data = str(type(exc)) + print("Exception caught: " + data) + finally: + print("request completed") + out.append(data) + + secsElapsed = time.time()-startMark + + TestUtils.printSummary(secsElapsed, gBytesDownloaded) diff --git a/Documentation/Network-Request-Tests/Readme.md b/Documentation/Network-Request-Tests/Readme.md new file mode 100644 index 000000000..4b9ed82d0 --- /dev/null +++ b/Documentation/Network-Request-Tests/Readme.md @@ -0,0 +1,43 @@ +These tests measure network performance when downloading Google P3DT tiles. + +Each one uses a slightly different methodology that could yield better / worse result. + +The test files are a subset of what's downloaded when running the Cesium for Unreal automation test `LocaleChrysler`. +It becomes a very useful comparison when running that automation test in Unreal. +It establishes a fastest possible baseline, where we can measure load speed as if there is no other game engine overhead. + + +Setup you machine +- +1) Install Unreal +2) Install the Cesium for Unreal plugin and samples project +3) Install DB Browser for SQLite +4) Install Python +5) Optionally install Wireshark + + +Start a Google P3DT session +- +1) Start any app that uses Google P3DT + * Could load level 12 from the Cesium for Unreal samples + * Could also run any of the Cesium Google PD3T automation tests +2) Find you sqlite cache at `C:\Users\\AppData\Local\UnrealEngine\5.4` +3) Open DB Browser for SQLite and open up cesium-request-cache.sqlite +4) You'll see many entries. Note the name `https://tile.googleapis.com/...` +5) In the name you should see the `session=somevalue` embedded +6) Copy this session value to `TestKey.py` + +> Note: Sessions don't last forever. You'll have to repeat these steps if running the same tests the next day + + +Run the network test +- +1) Run any of these +- CurlExeTest.py +- PyRequestLibTest.py +- PyUrlLib3Test.py +- ThreadedRequestsTest.py + +2) Note the output and the speed detected. You can optionally start a Wireshark session, then run the test, and view the speed results from Wireshark + +> Note: In TestUtils.py, you'll notice a set of 4 files as the test files to download. These as the first 4 files downloaded when running the Cesium for Unreal "LocaleChrysler". These filenames may get out of date. You might also want to download more / less files. Feel free to edit to your needs diff --git a/Documentation/Network-Request-Tests/TestKey.py b/Documentation/Network-Request-Tests/TestKey.py new file mode 100644 index 000000000..adecbcda0 --- /dev/null +++ b/Documentation/Network-Request-Tests/TestKey.py @@ -0,0 +1,2 @@ + +SessionKey = "session=CO_OwL-E99XVqgEQr7zVqgY&key=AIzaSyBQ7Wj99aTxRqET-22qYWGFcDCWgVDt89A" \ No newline at end of file diff --git a/Documentation/Network-Request-Tests/TestUtils.py b/Documentation/Network-Request-Tests/TestUtils.py new file mode 100644 index 000000000..3dcc239c5 --- /dev/null +++ b/Documentation/Network-Request-Tests/TestUtils.py @@ -0,0 +1,38 @@ + +UnrealStyleHeaders = { "Authorization" : "Bearer ", + "X-Cesium-Client" : "Cesium For Unreal", + "X-Cesium-Client-Version" : "2.0.0", + "X-Cesium-Client-Project" : "CesiumForUnrealSamples", + "X-Cesium-Client-Engine" : "Unreal Engine 5.3.1-28051148+++UE5+Release-5.3", + "X-Cesium-Client-OS" : "Windows 10 (22H2) [10.0.19045.3570] 10.0.19045.1.256.64bit", + "User-Agent" : "Mozilla/5.0 (Windows 10 (22H2) [10.0.19045.3570] 10.0.19045.1.256.64bit) Cesium For Unreal/2.0.0 (Project CesiumForUnrealSamples Engine Unreal Engine 5.3.1-28051148+++UE5+Release-5.3)", + "Content-Length" : "0", + "Expect" : "" } + +def buildUrlArray(sessionString): + uriArray = [] + uriArray.append("https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYuYnVsa21ldGFkYXRhLnBsYW5ldG9pZD1lYXJ0aCxidWxrX21ldGFkYXRhX2Vwb2NoPTk2MixwYXRoPTIxNjAsY2FjaGVfdmVyc2lvbj02.json") + uriArray.append("https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYuYnVsa21ldGFkYXRhLnBsYW5ldG9pZD1lYXJ0aCxidWxrX21ldGFkYXRhX2Vwb2NoPTk2MixwYXRoPTIxNDMsY2FjaGVfdmVyc2lvbj02.json") + uriArray.append("https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYuYnVsa21ldGFkYXRhLnBsYW5ldG9pZD1lYXJ0aCxidWxrX21ldGFkYXRhX2Vwb2NoPTk2MixwYXRoPTIxNDIsY2FjaGVfdmVyc2lvbj02.json") + uriArray.append("https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYuYnVsa21ldGFkYXRhLnBsYW5ldG9pZD1lYXJ0aCxidWxrX21ldGFkYXRhX2Vwb2NoPTk2MixwYXRoPTIwNjEsY2FjaGVfdmVyc2lvbj02.json") + + urlArray = [] + for uri in uriArray: + url = uri + "?" + sessionString + urlArray.append(url) + return urlArray + + +def printSummary(secsElapsed, bytesDownloaded): + msElapsed = secsElapsed * 1000 + print("\nBytes downloaded: " + str(bytesDownloaded)) + print ("Elapsed time: " + "%4f milliseconds" % (msElapsed) + "\n") + + bytesPerSecond = bytesDownloaded / secsElapsed + megabytesPerSecond = bytesPerSecond / 1024 / 1024 + megabitsPerSecond = megabytesPerSecond * 8 + + print("Bytes / second: " + str(bytesPerSecond)) + print("Megabytes / second: " + str(megabytesPerSecond)) + print("Megabits / second: " + str(megabitsPerSecond)) + print("\nDone\n") diff --git a/Documentation/Network-Request-Tests/ThreadedRequestsTest.py b/Documentation/Network-Request-Tests/ThreadedRequestsTest.py new file mode 100644 index 000000000..1c8427f4b --- /dev/null +++ b/Documentation/Network-Request-Tests/ThreadedRequestsTest.py @@ -0,0 +1,43 @@ +import sys +import time +import requests +import threading +import TestUtils +import TestKey + +def thread_function(url): + print("Loading URL...") + + response = requests.get(url, headers=TestUtils.UnrealStyleHeaders) + + global gBytesDownloaded + gBytesDownloaded += len(response.text); + + print(response.status_code) + + +if __name__ == "__main__": + global gBytesDownloaded + gBytesDownloaded = 0 + + sessionString = TestKey.SessionKey + + urlArray = TestUtils.buildUrlArray(sessionString) + + threadArray = [] + for url in urlArray: + print("Creating thread for ulr request...") + thread = threading.Thread(target=thread_function, args=(url,)) + threadArray.append(thread) + + startMark = time.time() + + for thread in threadArray: + thread.start() + + for thread in threadArray: + thread.join () + + secsElapsed = time.time()-startMark + + TestUtils.printSummary(secsElapsed, gBytesDownloaded)