def _get_webpage_result(self, url, host, protocol): s = requests.Session() headers = { "dnt": "1", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "sec-fetch-site": "none", "sec-fetch-mode": "navigate", "sec-fetch-user": "******", "sec-fetch-dest": "document", "accept-language": "en-GB,en-US;q=0.9,en;q=0.8", } start_time = time.time() try: r = s.get(url, headers=headers, timeout=self.download_timeout) except (ConnectionError, requests.ConnectionError) as e: return self._get_webpage_error("web-get", traceback=str(e)) except requests.exceptions.ReadTimeout as e: return self._get_webpage_error("web-timeout", traceback=str(e)) try: to_download = self._parse_html(r.text) except TypeError as e: return self._get_webpage_error("web-parse-rel", traceback=str(e)) try: asset_download_metrics = self._download_assets( s, to_download, host, protocol) except TypeError as e: return self._get_webpage_error("web-assets", traceback=str(e)) primary_download_size = len(r.text) asset_download_size = asset_download_metrics["asset_download_size"] elapsed_time = asset_download_metrics["completion_time"] - start_time download_rate = (primary_download_size + asset_download_size) * 8 / elapsed_time failed_asset_downloads = asset_download_metrics[ "failed_asset_downloads"] return WebpageMeasurementResult( id=self.id, url=url, download_rate=download_rate, download_rate_unit=NetworkUnit("bit/s"), download_size=primary_download_size + asset_download_size, download_size_unit=StorageUnit("B"), asset_count=len(to_download), failed_asset_downloads=failed_asset_downloads, elapsed_time=elapsed_time, elapsed_time_unit=TimeUnit("s"), errors=[], )
def _get_youtube_result(self, url): # Unique filename from process ID and timestamp file_dir = "{}/youtube-dl_{}".format(tempfile.gettempdir(), os.getpid()) filename = "{}/youtube-dl_{}/{}".format(tempfile.gettempdir(), os.getpid(), int(time.time())) params = { "quiet": True, "progress_hooks": [self._store_progress_dicts_hook], "outtmpl": filename, } ydl = youtube_dl.YoutubeDL(params=params) try: ydl.extract_info(url) except youtube_dl.utils.ExtractorError as e: return self._get_youtube_error("youtube-extractor", traceback=str(e)) except youtube_dl.utils.DownloadError as e: return self._get_youtube_error("youtube-download", traceback=str(e)) try: # Extract size and duration from final progress step download_size = self.progress_dicts[-1]["total_bytes"] elapsed_time = self.progress_dicts[-1]["elapsed"] # Speed is only reported in non-final steps download_rate = self.progress_dicts[-2]["speed"] * 8 except KeyError: return self._get_youtube_error("youtube-attribute", traceback=str(self.progress_dicts)) except IndexError: return self._get_youtube_error("youtube-progress_length", traceback=str(self.progress_dicts)) try: # Remove the created temp directory and all contents shutil.rmtree(file_dir) except FileNotFoundError as e: return self._get_youtube_error("youtube-no_directory", traceback=str(e)) return YouTubeMeasurementResult( id=self.id, url=self.url, download_rate=download_rate, download_rate_unit=NetworkUnit("bit/s"), download_size=download_size, download_size_unit=StorageUnit("B"), elapsed_time=elapsed_time, elapsed_time_unit=TimeUnit("s"), errors=[], )
def measure(self, share=False): """ @params share: Boolean determining whether to generate a PNG on speedtest.net displaying the result of the test. """ try: s = speedtest.Speedtest() except speedtest.ConfigRetrievalError as e: return self._get_speedtest_error("speedtest-config", traceback=str(e)) s.get_servers(self.servers) try: s.get_best_server() except speedtest.SpeedtestBestServerFailure as e: return self._get_speedtest_error("speedtest-best-server", traceback=str(e)) s.download() s.upload() if share: try: s.results.share() except speedtest.ShareResultsConnectFailure as e: return self._get_speedtest_error("speedtest-share", traceback=str(e)) results_dict = s.results.dict() try: return SpeedtestdotnetMeasurementResult( id=self.id, download_rate=float(results_dict["download"]), download_rate_unit=NetworkUnit("bit/s"), upload_rate=float(results_dict["upload"]), upload_rate_unit=NetworkUnit("bit/s"), data_received=(results_dict["bytes_received"]), data_received_unit=StorageUnit("B"), latency=float(results_dict["ping"]), server_name=results_dict["server"]["name"], server_id=results_dict["server"]["id"], server_sponsor=results_dict["server"]["sponsor"], server_host=results_dict["server"]["host"], errors=[], ) except ValueError as e: return self._get_speedtest_error("speedtest-convert", traceback=str(e))
def setUp(self) -> None: super().setUp() self.wpm = WebpageMeasurement("test", "http://validfakehost.com/test") self.simple_webpage_output = WebpageMeasurementResult( id="test", url="http://validfakehost.com/test", download_rate=100 / 1.00 * 8, download_rate_unit=NetworkUnit("bit/s"), download_size=100, download_size_unit=StorageUnit("B"), asset_count=123, failed_asset_downloads=0, elapsed_time=1.00, elapsed_time_unit=TimeUnit("s"), errors=[], ) self.simple_asset_download_metrics = { "asset_download_size": 90, "failed_asset_downloads": 0, "completion_time": 2.00, } self.get_error_result = WebpageMeasurementResult( id="test", url="http://validfakehost.com/test", download_rate_unit=None, download_rate=None, download_size=None, download_size_unit=None, asset_count=None, failed_asset_downloads=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="web-get", description=WEB_ERRORS.get("web-get", ""), traceback="[Errno -2] Name or service not known", ) ], )
def _get_url_result(self, thread_result): host = urllib.parse.urlparse(thread_result["url"]).netloc city = thread_result["location"]["city"] country = thread_result["location"]["country"] LatencyResult = LatencyMeasurement(self.id, host, count=PING_COUNT).measure()[0] return [ NetflixFastThreadResult( id=self.id, host=host, city=city, country=country, download_size=thread_result["download_size"], download_size_unit=StorageUnit("B"), download_rate=thread_result["download_rate"], download_rate_unit=NetworkUnit("bit/s"), elapsed_time=thread_result["elapsed_time"], elapsed_time_unit=TimeUnit("s"), errors=[], ), LatencyResult, ]
def _get_latency_results( # noqa: C901 self, host, count=4, include_individual_results=False ): """Perform the latency measurement. :param host: The host name to perform the test against. :param count: The number of pings to determine latency with. :param include_individual_results: Should each of the individualised ping iterations be included in the results? :return: A list of `LatencyMeasurementResult` and `LatencyIndividualMeasurementResult` if individual results are enabled. """ if host is None: return [self._get_latency_error("ping-no-server", host, traceback=None)] latency_out = subprocess.run( ["ping", "-c", "{c}".format(c=count), "{h}".format(h=host)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, ) # Note: only this error cares about stderr, other issues will be evident in stdout if latency_out.returncode != 0: return [ self._get_latency_error("ping-err", host, traceback=latency_out.stderr) ] try: latency_data = latency_out.stdout.split("\n")[-2] except IndexError: return [ self._get_latency_error( "ping-split", host, traceback=latency_out.stdout ) ] matches = LATENCY_OUTPUT_REGEX.search(latency_data) try: match_data = matches.groupdict() except AttributeError: return [ self._get_latency_error( "ping-regex", host, traceback=latency_out.stdout ) ] if len(match_data.keys()) != 4: return [ self._get_latency_error( "ping-regex", host, traceback=latency_out.stdout ) ] match_data = matches.groupdict() try: maximum_latency = float(match_data.get("maximum_latency")) except (TypeError, ValueError): return [ self._get_latency_error( "ping-maximum-latency", host, traceback=latency_out.stdout ) ] try: minimum_latency = float(match_data.get("minimum_latency")) except (TypeError, ValueError): return [ self._get_latency_error( "ping-minimum-latency", host, traceback=latency_out.stdout ) ] try: average_latency = float(match_data.get("average_latency")) except (TypeError, ValueError): return [ self._get_latency_error( "ping-average-latency", host, traceback=latency_out.stdout ) ] try: median_deviation = float(match_data.get("median_deviation")) except (TypeError, ValueError): return [ self._get_latency_error( "ping-median_deviation", host, traceback=latency_out.stdout ) ] try: latency_data = latency_out.stdout.split("\n")[-3] except IndexError: return [ self._get_latency_error( "ping-split", host, traceback=latency_out.stdout ) ] matches = LATENCY_PACKETS_REGEX.search(latency_data) try: match_data = matches.groupdict() except AttributeError: return [ self._get_latency_error( "ping-regex", host, traceback=latency_out.stdout ) ] packets_transmitted = int(match_data.get("packets_transmitted")) packets_received = int(match_data.get("packets_received")) packet_loss = float(match_data.get("packet_loss")) elapsed_time = float(match_data.get("time")) elapsed_time_unit = match_data.get("time_unit") results = [ LatencyMeasurementResult( id=self.id, host=host, minimum_latency=minimum_latency, average_latency=average_latency, maximum_latency=maximum_latency, median_deviation=median_deviation, packets_transmitted=packets_transmitted, packets_received=packets_received, packets_lost=packet_loss, packets_lost_unit=RatioUnit.percentage, elapsed_time=elapsed_time, elapsed_time_unit=TimeUnit(elapsed_time_unit), errors=[], ) ] if include_individual_results: matches = LATENCY_INDIVIDUAL_PING_REGEX.findall(latency_out.stdout) for match in matches: results.append( LatencyIndividualMeasurementResult( id=self.id, host=host, errors=[], packet_size=match[0], packet_size_unit=StorageUnit(match[1].replace("bytes", "B")), reverse_dns_address=match[2], ip_address=match[3], icmp_sequence=match[4], time_to_live=match[5], elapsed_time=match[6], elapsed_time_unit=TimeUnit(match[7]), ) ) return results
def _get_fast_result(self): s = requests.Session() try: resp = self._get_response(s) except ConnectionError as e: return self._get_netflix_error("netflix-response", traceback=str(e)) try: script = re.search(r'<script src="(.*?)">', resp.text).group(1) except AttributeError: return self._get_netflix_error("netflix-script-regex", traceback=resp.text) try: script_resp = s.get( "https://fast.com{script}".format(script=script)) except ConnectionError as e: return self._get_netflix_error("netflix-script-response", traceback=str(e)) try: token = re.search(r'token:"(.*?)"', script_resp.text).group(1) except AttributeError: return self._get_netflix_error("netflix-token-regex", traceback=script_resp.text) try: self._query_api(s, token) except ConnectionError as e: return self._get_netflix_error("netflix-api-response", traceback=str(e)) except json.decoder.JSONDecodeError as e: return self._get_netflix_error("netflix-api-json", traceback=str(e)) except TypeError as e: return self._get_netflix_error("netflix-api-parse", traceback=str(e)) except KeyError as e: return self._get_netflix_error("netflix-api-parse", traceback=str(e)) try: conns = [ self._get_connection(target["url"]) for target in self.thread_results ] except ConnectionError as e: return self._get_netflix_error("netflix-connection", traceback=str(e)) fast_data = self._manage_threads(conns) return NetflixFastMeasurementResult( id=self.id, download_rate=float(fast_data["speed_bits"]), download_rate_unit=NetworkUnit("bit/s"), download_size=float(fast_data["total"]), download_size_unit=StorageUnit("B"), asn=self.client_data["asn"], ip=self.client_data["ip"], isp=self.client_data["isp"], city=self.client_data["location"]["city"], country=self.client_data["location"]["country"], urlcount=self.urlcount, reason_terminated=fast_data["reason_terminated"], errors=[], )
def setUp(self) -> None: super().setUp() self.nft = NetflixFastMeasurement("1", urlcount=3, terminate_on_thread_complete=True) self.api_response_three = { "client": { "location": { "city": "HBox City", "country": "HBoxtopia" }, "isp": "ServiceProvider", "asn": "0000", "ip": "0000:0000:000a:0000:0c00:0b00:a0a0:f0f0", }, "targets": [ { "location": { "city": "Foreign City One", "country": "Foreign Country One", }, "name": "https://afakeurl.1.notreal.net/speedtest", "url": "https://afakeurl.1.notreal.net/speedtest", }, { "location": { "city": "Foreign City Two", "country": "Foreign Country Two", }, "name": "https://afakeurl.2.notreal.net/speedtest", "url": "https://afakeurl.2.notreal.net/speedtest", }, { "location": { "city": "Foreign City Three", "country": "Foreign Country Three", }, "name": "https://afakeurl.3.notreal.net/speedtest", "url": "https://afakeurl.3.notreal.net/speedtest", }, ], } self.fast_data_three = { "speed_bits": 1234, "total": 4321, "reason_terminated": "fake_reason", } self.fast_result_three = NetflixFastMeasurementResult( id="1", download_rate=float(self.fast_data_three["speed_bits"]), download_rate_unit=NetworkUnit("bit/s"), download_size=float(self.fast_data_three["total"]), download_size_unit=StorageUnit("B"), asn=self.api_response_three["client"]["asn"], ip=self.api_response_three["client"]["ip"], isp=self.api_response_three["client"]["isp"], city=self.api_response_three["client"]["location"]["city"], country=self.api_response_three["client"]["location"]["country"], urlcount=3, reason_terminated=self.fast_data_three["reason_terminated"], errors=[], ) self.thread_result_three_list = [ [ NetflixFastThreadResult( id="1", host="afakeurl.1.notreal.net", city=self.api_response_three["targets"][0]["location"] ["city"], country=self.api_response_three["targets"][0]["location"] ["country"], download_size=0, download_size_unit=StorageUnit("B"), download_rate=0, download_rate_unit=NetworkUnit("bit/s"), elapsed_time=0, elapsed_time_unit=TimeUnit("s"), errors=[], ), LatencyMeasurementResult( id="1", host="afakeurl.1.notreal.net", minimum_latency=0, average_latency=0, maximum_latency=0, median_deviation=0, packets_transmitted=0, packets_received=0, packets_lost=0, packets_lost_unit=RatioUnit("%"), elapsed_time=0, elapsed_time_unit=TimeUnit("d"), errors=[], ), ], [ NetflixFastThreadResult( id="1", host="afakeurl.1.notreal.net", city=self.api_response_three["targets"][1]["location"] ["city"], country=self.api_response_three["targets"][1]["location"] ["country"], download_size=0, download_size_unit=StorageUnit("B"), download_rate=0, download_rate_unit=NetworkUnit("bit/s"), elapsed_time=0, elapsed_time_unit=TimeUnit("s"), errors=[], ), LatencyMeasurementResult( id="1", host="afakeurl.1.notreal.net", minimum_latency=0, average_latency=0, maximum_latency=0, median_deviation=0, packets_transmitted=0, packets_received=0, packets_lost=0, packets_lost_unit=RatioUnit("%"), elapsed_time=0, elapsed_time_unit=TimeUnit("d"), errors=[], ), ], [ NetflixFastThreadResult( id="1", host="afakeurl.1.notreal.net", city=self.api_response_three["targets"][2]["location"] ["city"], country=self.api_response_three["targets"][2]["location"] ["country"], download_size=0, download_size_unit=StorageUnit("B"), download_rate=0, download_rate_unit=NetworkUnit("bit/s"), elapsed_time=0, elapsed_time_unit=TimeUnit("s"), errors=[], ), LatencyMeasurementResult( id="1", host="afakeurl.1.notreal.net", minimum_latency=0, average_latency=0, maximum_latency=0, median_deviation=0, packets_transmitted=0, packets_received=0, packets_lost=0, packets_lost_unit=RatioUnit("%"), elapsed_time=0, elapsed_time_unit=TimeUnit("d"), errors=[], ), ], ]
def setUp(self) -> None: super().setUp() self.id = "1" self.stdnm = SpeedtestdotnetMeasurement("1") self.sample_results_dict_valid = { "download": 93116804.64881887, "upload": 19256654.06593738, "ping": 17.054, "server": { "url": "http://fake.site:8080/speedtest/upload.php", "lat": "-33.8600", "lon": "151.2111", "name": "HonestyVille", "country": "Australia", "cc": "AU", "sponsor": "'Yes' HonestyBox", "id": "1267", "url2": "http://s1.fake.site:8080/speedtest/upload.php", "host": "fake.site:8080", "d": 53.70823411720704, "latency": 17.054, }, "timestamp": "2020-03-11T07:09:52.890803Z", "bytes_sent": 25591808, "bytes_received": 116746522, "share": "http://www.faketest.net/result/9117363621.png", "client": { "ip": "101.166.54.134", "lat": "-33.4102", "lon": "151.4225", "isp": "HonestyBox Internet", "isprating": "3.7", "rating": "0", "ispdlavg": "0", "ispulavg": "0", "loggedin": "0", "country": "AU", }, } self.sample_result_valid = SpeedtestdotnetMeasurementResult( id=self.id, download_rate=93116804.64881887, download_rate_unit=NetworkUnit("bit/s"), upload_rate=19256654.06593738, upload_rate_unit=NetworkUnit("bit/s"), data_received=116746522, data_received_unit=StorageUnit("B"), latency=17.054, server_name="HonestyVille", server_id="1267", server_sponsor="'Yes' HonestyBox", server_host="fake.site:8080", errors=[], ) self.sample_result_configretrieval = SpeedtestdotnetMeasurementResult( id=self.id, download_rate=None, download_rate_unit=None, upload_rate=None, upload_rate_unit=None, data_received=None, data_received_unit=None, latency=None, server_name=None, server_id=None, server_sponsor=None, server_host=None, errors=[ Error( key="speedtest-config", description=SPEEDTEST_ERRORS.get("speedtest-config", ""), traceback="<urlopen error [Errno -3] Temporary failure in name resolution>", ) ], ) self.sample_result_bestserver = SpeedtestdotnetMeasurementResult( id=self.id, download_rate=None, download_rate_unit=None, upload_rate=None, upload_rate_unit=None, data_received=None, data_received_unit=None, latency=None, server_name=None, server_id=None, server_sponsor=None, server_host=None, errors=[ Error( key="speedtest-best-server", description=SPEEDTEST_ERRORS.get("speedtest-best-server", ""), traceback="Unable to connect to servers to test latency.", ) ], ) self.sample_result_share = SpeedtestdotnetMeasurementResult( id=self.id, download_rate=None, download_rate_unit=None, upload_rate=None, upload_rate_unit=None, data_received=None, data_received_unit=None, latency=None, server_name=None, server_id=None, server_sponsor=None, server_host=None, errors=[ Error( key="speedtest-share", description=SPEEDTEST_ERRORS.get("speedtest-share", ""), traceback="<urlopen error [Errno -3] Temporary failure in name resolution>", ) ], )
def setUp(self) -> None: super().setUp() self.id = "1" self.test_url = "https://www.youtube.com/watch?v=1233zthJUf31MA" self.ytm = YouTubeMeasurement(self.id, self.test_url) self.mock_progress_dicts = [ { "_eta_str": "Unknown ETA", "_percent_str": " 0.0%", "_speed_str": "Unknown speed", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 1024, "elapsed": 0.13415765762329102, "eta": None, "filename": "/tmp/youtube-dl_7954/1596695025_Portland Protest.mp4", "speed": None, "status": "downloading", "tmpfilename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4.part", "total_bytes": 163492702, }, { "_eta_str": "00:00", "_percent_str": "100.0%", "_speed_str": "12.34MiB/s", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 163492702, "elapsed": 13.792589902877808, "eta": 0, "filename": "/tmp/youtube-dl_31918/1596679305_Portland Protest.mp4", "speed": 12345678.012500000, "status": "downloading", "tmpfilename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4.part", "total_bytes": 163492702, }, { "_elapsed_str": "12:34", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 123456789, "elapsed": 12.345678987654321, "filename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4", "status": "finished", "total_bytes": 123456789, }, ] self.mock_progress_dicts_missing_attribute = [ { "_eta_str": "Unknown ETA", "_percent_str": " 0.0%", "_speed_str": "Unknown speed", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 1024, "elapsed": 0.13415765762329102, "eta": None, "filename": "/tmp/youtube-dl_7954/1596695025_Portland Protest.mp4", "speed": None, "status": "downloading", "tmpfilename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4.part", "total_bytes": 163492702, }, { "_eta_str": "00:00", "_percent_str": "100.0%", "_speed_str": "12.34MiB/s", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 163492702, "elapsed": 13.792589902877808, "eta": 0, "filename": "/tmp/youtube-dl_31918/1596679305_Portland Protest.mp4", "speed": 12345678.012500000, "status": "downloading", "tmpfilename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4.part", "total_bytes": 163492702, }, { "_elapsed_str": "12:34", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 123456789, "elapsed": 12.345678987654321, "filename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4", "status": "finished", "BADotal_bytes": 123456789, }, ] self.mock_progress_dicts_only_final = [{ "_elapsed_str": "12:34", "_total_bytes_str": "123.4MiB", "downloaded_bytes": 123456789, "elapsed": 12.345678987654321, "filename": "/tmp/youtube-dl_31918/1234567890_Fake Video.mp4", "status": "finished", "total_bytes": 123456789, }] self.mock_valid_youtube_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=98765424.1, download_rate_unit=NetworkUnit("bit/s"), download_size=123456789, download_size_unit=StorageUnit("B"), elapsed_time=12.345678987654321, elapsed_time_unit=TimeUnit("s"), errors=[], ) self.mock_extraction_fail_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-extractor", description=YOUTUBE_ERRORS.get("youtube-extractor", ""), traceback= "Extraction failed!; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.", ) ], ) self.mock_download_fail_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-download", description=YOUTUBE_ERRORS.get("youtube-download", ""), traceback="Download failed!", ) ], ) self.mock_missing_attribute_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-attribute", description=YOUTUBE_ERRORS.get("youtube-attribute", ""), traceback=str(self.mock_progress_dicts_missing_attribute), ) ], ) self.mock_final_only_result = (YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-progress_length", description=YOUTUBE_ERRORS.get("youtube-progress_length", ""), traceback=str(self.mock_progress_dicts_only_final), ) ], ), ) self.mock_final_only_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-progress_length", description=YOUTUBE_ERRORS.get("youtube-progress_length", ""), traceback=str(self.mock_progress_dicts_only_final), ) ], ) self.mock_file_remove_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-file", description=YOUTUBE_ERRORS.get("youtube-file", ""), traceback= "[Errno 2] No such file or directory: 'example_file'", ) ], ) self.mock_directory_remove_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-no_directory", description=YOUTUBE_ERRORS.get("youtube-no_directory", ""), traceback= "[Errno 2] No such file or directory: 'example_dir'", ) ], ) self.mock_directory_remove_nonempty_result = YouTubeMeasurementResult( id=self.id, url=self.test_url, download_rate=None, download_rate_unit=None, download_size=None, download_size_unit=None, elapsed_time=None, elapsed_time_unit=None, errors=[ Error( key="youtube-directory_nonempty", description=YOUTUBE_ERRORS.get( "youtube-directory_nonempty", ""), traceback="[Errno 39] Directory not empty: 'example_dir'", ) ], )