Repository: modin-project/modin

Issue:
TST: temp files left behind after pytest modin/pandas/test/
I see 200kx99.csv and modin/pandas/test/io_tests_data/ left behind.

could reuse pandas' tm.ensure_clean for this


Discussion:
@jbrockmendel thanks for opening this issue. The culprit of 200kx99.csv seems to be `test___setitem__with_mismatched_partitions` in `test_indexing.py`. It also looks like we make no effort to clean up `IO_OPS_DATA_DIR`. 

Resolving patch:
diff --git a/modin/conftest.py b/modin/conftest.py
--- a/modin/conftest.py
+++ b/modin/conftest.py
@@ -60,13 +60,8 @@ def _saving_make_api_url(token, _make_api_url=modin.utils._make_api_url):
     make_default_file,
     teardown_test_files,
     NROWS,
-    IO_OPS_DATA_DIR,
 )
 
-# create test data dir if it is not exists yet
-if not os.path.exists(IO_OPS_DATA_DIR):
-    os.mkdir(IO_OPS_DATA_DIR)
-
 
 def pytest_addoption(parser):
     parser.addoption(
@@ -516,9 +511,6 @@ def _sql_connection(filename, table=""):
 
     yield _sql_connection
 
-    # Teardown the fixture
-    teardown_test_files(filenames)
-
 
 @pytest.fixture(scope="class")
 def TestReadGlobCSVFixture():


Test patch:
diff --git a/modin/experimental/pandas/test/test_io_exp.py b/modin/experimental/pandas/test/test_io_exp.py
--- a/modin/experimental/pandas/test/test_io_exp.py
+++ b/modin/experimental/pandas/test/test_io_exp.py
@@ -15,14 +15,15 @@
 import glob
 import json
 import numpy as np
+import os
 import pandas
+from pandas._testing import ensure_clean, ensure_clean_dir
 import pytest
 import modin.experimental.pandas as pd
 from modin.config import Engine
 from modin.utils import get_current_execution
 from modin.pandas.test.utils import (
     df_equals,
-    get_unique_filename,
     teardown_test_files,
     test_data,
     eval_general,
@@ -37,28 +38,29 @@
 )
 def test_from_sql_distributed(make_sql_connection):  # noqa: F811
     if Engine.get() == "Ray":
-        filename = "test_from_sql_distributed.db"
-        table = "test_from_sql_distributed"
-        conn = make_sql_connection(filename, table)
-        query = "select * from {0}".format(table)
-
-        pandas_df = pandas.read_sql(query, conn)
-        modin_df_from_query = pd.read_sql(
-            query,
-            conn,
-            partition_column="col1",
-            lower_bound=0,
-            upper_bound=6,
-            max_sessions=2,
-        )
-        modin_df_from_table = pd.read_sql(
-            table,
-            conn,
-            partition_column="col1",
-            lower_bound=0,
-            upper_bound=6,
-            max_sessions=2,
-        )
+        with ensure_clean_dir() as dirname:
+            filename = "test_from_sql_distributed.db"
+            table = "test_from_sql_distributed"
+            conn = make_sql_connection(os.path.join(dirname, filename), table)
+            query = "select * from {0}".format(table)
+
+            pandas_df = pandas.read_sql(query, conn)
+            modin_df_from_query = pd.read_sql(
+                query,
+                conn,
+                partition_column="col1",
+                lower_bound=0,
+                upper_bound=6,
+                max_sessions=2,
+            )
+            modin_df_from_table = pd.read_sql(
+                table,
+                conn,
+                partition_column="col1",
+                lower_bound=0,
+                upper_bound=6,
+                max_sessions=2,
+            )
 
         df_equals(modin_df_from_query, pandas_df)
         df_equals(modin_df_from_table, pandas_df)
@@ -69,16 +71,17 @@ def test_from_sql_distributed(make_sql_connection):  # noqa: F811
     reason="Dask does not have experimental API",
 )
 def test_from_sql_defaults(make_sql_connection):  # noqa: F811
-    filename = "test_from_sql_distributed.db"
-    table = "test_from_sql_distributed"
-    conn = make_sql_connection(filename, table)
-    query = "select * from {0}".format(table)
+    with ensure_clean_dir() as dirname:
+        filename = "test_from_sql_distributed.db"
+        table = "test_from_sql_distributed"
+        conn = make_sql_connection(os.path.join(dirname, filename), table)
+        query = "select * from {0}".format(table)
 
-    pandas_df = pandas.read_sql(query, conn)
-    with pytest.warns(UserWarning):
-        modin_df_from_query = pd.read_sql(query, conn)
-    with pytest.warns(UserWarning):
-        modin_df_from_table = pd.read_sql(table, conn)
+        pandas_df = pandas.read_sql(query, conn)
+        with pytest.warns(UserWarning):
+            modin_df_from_query = pd.read_sql(query, conn)
+        with pytest.warns(UserWarning):
+            modin_df_from_table = pd.read_sql(table, conn)
 
     df_equals(modin_df_from_query, pandas_df)
     df_equals(modin_df_from_table, pandas_df)
@@ -259,15 +262,11 @@ def test_distributed_pickling(filename, compression):
     reason=f"{Engine.get()} does not have experimental read_custom_text API",
 )
 def test_read_custom_json_text():
-    filename = get_unique_filename(extension="json")
-
     def _generate_json(file_name, nrows, ncols):
         data = np.random.rand(nrows, ncols)
         df = pandas.DataFrame(data, columns=[f"col{x}" for x in range(ncols)])
         df.to_json(file_name, lines=True, orient="records")
 
-    _generate_json(filename, 64, 8)
-
     # Custom parser allows us to add some specifics to reading files,
     # which is not available through the ready-made API.
     # For example, the parser allows us to reduce the amount of RAM
@@ -281,15 +280,18 @@ def _custom_parser(io_input, **kwargs):
                 result[key].append(obj[key])
         return pandas.DataFrame(result).rename(columns={"col0": "testID"})
 
-    df1 = pd.read_custom_text(
-        filename,
-        columns=["testID", "col1", "col3"],
-        custom_parser=_custom_parser,
-        is_quoting=False,
-    )
-    df2 = pd.read_json(filename, lines=True)[["col0", "col1", "col3"]].rename(
-        columns={"col0": "testID"}
-    )
+    with ensure_clean() as filename:
+        _generate_json(filename, 64, 8)
+
+        df1 = pd.read_custom_text(
+            filename,
+            columns=["testID", "col1", "col3"],
+            custom_parser=_custom_parser,
+            is_quoting=False,
+        )
+        df2 = pd.read_json(filename, lines=True)[["col0", "col1", "col3"]].rename(
+            columns={"col0": "testID"}
+        )
     df_equals(df1, df2)
 
 
@@ -298,8 +300,6 @@ def _custom_parser(io_input, **kwargs):
     reason=f"{Engine.get()} does not have experimental API",
 )
 def test_read_evaluated_dict():
-    filename = get_unique_filename(extension="json")
-
     def _generate_evaluated_dict(file_name, nrows, ncols):
         result = {}
         keys = [f"col{x}" for x in range(ncols)]
@@ -312,8 +312,6 @@ def _generate_evaluated_dict(file_name, nrows, ncols):
                 _file.write(str(result))
                 _file.write("\n")
 
-    _generate_evaluated_dict(filename, 64, 8)
-
     # This parser allows us to read a format not supported by other reading functions
     def _custom_parser(io_input, **kwargs):
         cat_list = []
@@ -324,13 +322,6 @@ def _custom_parser(io_input, **kwargs):
             asin_list.append(obj["col2"])
         return pandas.DataFrame({"col1": asin_list, "col2": cat_list})
 
-    df1 = pd.read_custom_text(
-        filename,
-        columns=["col1", "col2"],
-        custom_parser=_custom_parser,
-    )
-    assert df1.shape == (64, 2)
-
     def columns_callback(io_input, **kwargs):
         columns = None
         for line in io_input:
@@ -338,7 +329,17 @@ def columns_callback(io_input, **kwargs):
             break
         return columns
 
-    df2 = pd.read_custom_text(
-        filename, columns=columns_callback, custom_parser=_custom_parser
-    )
+    with ensure_clean() as filename:
+        _generate_evaluated_dict(filename, 64, 8)
+
+        df1 = pd.read_custom_text(
+            filename,
+            columns=["col1", "col2"],
+            custom_parser=_custom_parser,
+        )
+        assert df1.shape == (64, 2)
+
+        df2 = pd.read_custom_text(
+            filename, columns=columns_callback, custom_parser=_custom_parser
+        )
     df_equals(df1, df2)
diff --git a/modin/pandas/test/dataframe/test_indexing.py b/modin/pandas/test/dataframe/test_indexing.py
--- a/modin/pandas/test/dataframe/test_indexing.py
+++ b/modin/pandas/test/dataframe/test_indexing.py
@@ -15,6 +15,7 @@
 import numpy as np
 import pandas
 from pandas.testing import assert_index_equal
+from pandas._testing import ensure_clean
 import matplotlib
 import modin.pandas as pd
 import sys
@@ -1894,13 +1895,13 @@ def test___setitem__partitions_aligning():
 
 
 def test___setitem__with_mismatched_partitions():
-    fname = "200kx99.csv"
-    np.savetxt(fname, np.random.randint(0, 100, size=(200_000, 99)), delimiter=",")
-    modin_df = pd.read_csv(fname)
-    pandas_df = pandas.read_csv(fname)
-    modin_df["new"] = pd.Series(list(range(len(modin_df))))
-    pandas_df["new"] = pandas.Series(list(range(len(pandas_df))))
-    df_equals(modin_df, pandas_df)
+    with ensure_clean(".csv") as fname:
+        np.savetxt(fname, np.random.randint(0, 100, size=(200_000, 99)), delimiter=",")
+        modin_df = pd.read_csv(fname)
+        pandas_df = pandas.read_csv(fname)
+        modin_df["new"] = pd.Series(list(range(len(modin_df))))
+        pandas_df["new"] = pandas.Series(list(range(len(pandas_df))))
+        df_equals(modin_df, pandas_df)
 
 
 def test___setitem__mask():
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -18,6 +18,7 @@
 from pandas.errors import ParserWarning
 import pandas._libs.lib as lib
 from pandas.core.dtypes.common import is_list_like
+from pandas._testing import ensure_clean, ensure_clean_dir
 from pathlib import Path
 from collections import OrderedDict
 from modin.config.envvars import MinPartitionSize
@@ -42,7 +43,6 @@
 import os
 from scipy import sparse
 import sys
-import shutil
 import sqlalchemy as sa
 import csv
 import tempfile
@@ -61,8 +61,6 @@
     dummy_decorator,
     create_test_dfs,
     COMP_TO_EXT,
-    teardown_test_file,
-    teardown_test_files,
     generate_dataframe,
     default_to_pandas_ignore_string,
     parse_dates_values_by_id,
@@ -150,22 +148,20 @@ def parquet_eval_to_file(modin_obj, pandas_obj, fn, extension, **fn_kwargs):
     extension : str
         Extension of the test file.
     """
-    unique_filename_modin = get_unique_filename(extension=extension)
-    unique_filename_pandas = get_unique_filename(extension=extension)
+    with ensure_clean_dir() as dirname:
+        unique_filename_modin = get_unique_filename(
+            extension=extension, data_dir=dirname
+        )
+        unique_filename_pandas = get_unique_filename(
+            extension=extension, data_dir=dirname
+        )
 
-    try:
         getattr(modin_obj, fn)(unique_filename_modin, **fn_kwargs)
         getattr(pandas_obj, fn)(unique_filename_pandas, **fn_kwargs)
 
         pandas_df = pandas.read_parquet(unique_filename_pandas)
         modin_df = pd.read_parquet(unique_filename_modin)
-        df_equals(pandas_df, modin_df)
-    finally:
-        teardown_test_file(unique_filename_pandas)
-        try:
-            teardown_test_file(unique_filename_modin)
-        except IsADirectoryError:
-            shutil.rmtree(unique_filename_modin)
+    df_equals(pandas_df, modin_df)
 
 
 def eval_to_file(modin_obj, pandas_obj, fn, extension, **fn_kwargs):
@@ -177,10 +173,14 @@ def eval_to_file(modin_obj, pandas_obj, fn, extension, **fn_kwargs):
         fn: name of the method, that should be tested.
         extension: Extension of the test file.
     """
-    unique_filename_modin = get_unique_filename(extension=extension)
-    unique_filename_pandas = get_unique_filename(extension=extension)
+    with ensure_clean_dir() as dirname:
+        unique_filename_modin = get_unique_filename(
+            extension=extension, data_dir=dirname
+        )
+        unique_filename_pandas = get_unique_filename(
+            extension=extension, data_dir=dirname
+        )
 
-    try:
         # parameter `max_retries=0` is set for `to_csv` function on Ray engine,
         # in order to increase the stability of tests, we repeat the call of
         # the entire function manually
@@ -198,8 +198,6 @@ def eval_to_file(modin_obj, pandas_obj, fn, extension, **fn_kwargs):
         getattr(pandas_obj, fn)(unique_filename_pandas, **fn_kwargs)
 
         assert assert_files_eq(unique_filename_modin, unique_filename_pandas)
-    finally:
-        teardown_test_files([unique_filename_modin, unique_filename_pandas])
 
 
 @pytest.fixture
@@ -232,23 +230,23 @@ class TestCsv:
     def test_read_csv_delimiters(
         self, make_csv_file, sep, delimiter, decimal, thousands
     ):
-        unique_filename = get_unique_filename()
-        make_csv_file(
-            filename=unique_filename,
-            delimiter=delimiter,
-            thousands_separator=thousands,
-            decimal_separator=decimal,
-        )
+        with ensure_clean(".csv") as unique_filename:
+            make_csv_file(
+                filename=unique_filename,
+                delimiter=delimiter,
+                thousands_separator=thousands,
+                decimal_separator=decimal,
+            )
 
-        eval_io(
-            fn_name="read_csv",
-            # read_csv kwargs
-            filepath_or_buffer=unique_filename,
-            delimiter=delimiter,
-            sep=sep,
-            decimal=decimal,
-            thousands=thousands,
-        )
+            eval_io(
+                fn_name="read_csv",
+                # read_csv kwargs
+                filepath_or_buffer=unique_filename,
+                delimiter=delimiter,
+                sep=sep,
+                decimal=decimal,
+                thousands=thousands,
+            )
 
     # Column and Index Locations and Names tests
     @pytest.mark.parametrize("header", ["infer", None, 0])
@@ -388,36 +386,38 @@ def test_read_csv_parsing_2(
             pytest.xfail(
                 reason="The reason of tests fail in `cloud` mode is unknown for now - issue #2340"
             )
-        if encoding:
-            unique_filename = get_unique_filename()
-            make_csv_file(
-                filename=unique_filename,
-                encoding=encoding,
-            )
-        kwargs = {
-            "filepath_or_buffer": unique_filename
-            if encoding
-            else pytest.csvs_names["test_read_csv_regular"],
-            "header": header,
-            "skiprows": skiprows,
-            "nrows": nrows,
-            "names": names,
-            "encoding": encoding,
-        }
+        with ensure_clean(".csv") as unique_filename:
+            if encoding:
+                make_csv_file(
+                    filename=unique_filename,
+                    encoding=encoding,
+                )
+            kwargs = {
+                "filepath_or_buffer": unique_filename
+                if encoding
+                else pytest.csvs_names["test_read_csv_regular"],
+                "header": header,
+                "skiprows": skiprows,
+                "nrows": nrows,
+                "names": names,
+                "encoding": encoding,
+            }
 
-        if Engine.get() != "Python":
-            df = pandas.read_csv(**dict(kwargs, nrows=1))
-            # in that case first partition will contain str
-            if df[df.columns[0]][df.index[0]] in ["c1", "col1", "c3", "col3"]:
-                pytest.xfail("read_csv incorrect output with float data - issue #2634")
-        eval_io(
-            fn_name="read_csv",
-            check_exception_type=None,  # issue #2320
-            raising_exceptions=None,
-            check_kwargs_callable=not callable(skiprows),
-            # read_csv kwargs
-            **kwargs,
-        )
+            if Engine.get() != "Python":
+                df = pandas.read_csv(**dict(kwargs, nrows=1))
+                # in that case first partition will contain str
+                if df[df.columns[0]][df.index[0]] in ["c1", "col1", "c3", "col3"]:
+                    pytest.xfail(
+                        "read_csv incorrect output with float data - issue #2634"
+                    )
+            eval_io(
+                fn_name="read_csv",
+                check_exception_type=None,  # issue #2320
+                raising_exceptions=None,
+                check_kwargs_callable=not callable(skiprows),
+                # read_csv kwargs
+                **kwargs,
+            )
 
     @pytest.mark.parametrize("true_values", [["Yes"], ["Yes", "true"], None])
     @pytest.mark.parametrize("false_values", [["No"], ["No", "false"], None])
@@ -451,15 +451,15 @@ def test_read_csv_parsing_3(
         )
 
     def test_read_csv_skipinitialspace(self):
-        unique_filename = get_unique_filename()
-        str_initial_spaces = (
-            "col1,col2,col3,col4\n"
-            + "five,  six,  seven,  eight\n"
-            + "    five,    six,    seven,    eight\n"
-            + "five, six,  seven,   eight\n"
-        )
+        with ensure_clean(".csv") as unique_filename:
+            str_initial_spaces = (
+                "col1,col2,col3,col4\n"
+                + "five,  six,  seven,  eight\n"
+                + "    five,    six,    seven,    eight\n"
+                + "five, six,  seven,   eight\n"
+            )
 
-        eval_io_from_str(str_initial_spaces, unique_filename, skipinitialspace=True)
+            eval_io_from_str(str_initial_spaces, unique_filename, skipinitialspace=True)
 
     @pytest.mark.parametrize(
         "test_case",
@@ -470,30 +470,31 @@ def test_read_csv_squeeze(self, request, test_case):
             pytest.xfail(
                 reason="Error EOFError: stream has been closed in `modin in the cloud` mode - issue #3329"
             )
-        unique_filename = get_unique_filename()
-
-        str_single_element = "1"
-        str_single_col = "1\n2\n3\n"
-        str_four_cols = "1, 2, 3, 4\n5, 6, 7, 8\n9, 10, 11, 12\n"
-        case_to_data = {
-            "single_element": str_single_element,
-            "single_column": str_single_col,
-            "multiple_columns": str_four_cols,
-        }
+        with ensure_clean(".csv") as unique_filename:
+            str_single_element = "1"
+            str_single_col = "1\n2\n3\n"
+            str_four_cols = "1, 2, 3, 4\n5, 6, 7, 8\n9, 10, 11, 12\n"
+            case_to_data = {
+                "single_element": str_single_element,
+                "single_column": str_single_col,
+                "multiple_columns": str_four_cols,
+            }
 
-        eval_io_from_str(case_to_data[test_case], unique_filename, squeeze=True)
-        eval_io_from_str(
-            case_to_data[test_case], unique_filename, header=None, squeeze=True
-        )
+            eval_io_from_str(case_to_data[test_case], unique_filename, squeeze=True)
+            eval_io_from_str(
+                case_to_data[test_case], unique_filename, header=None, squeeze=True
+            )
 
     def test_read_csv_mangle_dupe_cols(self):
         if StorageFormat.get() == "Omnisci":
             pytest.xfail(
                 "processing of duplicated columns in OmniSci storage format is not supported yet - issue #3080"
             )
-        unique_filename = get_unique_filename()
-        str_non_unique_cols = "col,col,col,col\n5, 6, 7, 8\n9, 10, 11, 12\n"
-        eval_io_from_str(str_non_unique_cols, unique_filename, mangle_dupe_cols=True)
+        with ensure_clean() as unique_filename:
+            str_non_unique_cols = "col,col,col,col\n5, 6, 7, 8\n9, 10, 11, 12\n"
+            eval_io_from_str(
+                str_non_unique_cols, unique_filename, mangle_dupe_cols=True
+            )
 
     # NA and Missing Data Handling tests
     @pytest.mark.parametrize("na_values", ["custom_nan", "73"])
@@ -630,24 +631,24 @@ def test_read_csv_compression(self, make_csv_file, compression, encoding, engine
             pytest.xfail(
                 "Parallel read_csv does not support compression with older pandas"
             )
-        unique_filename = get_unique_filename()
-        make_csv_file(
-            filename=unique_filename, encoding=encoding, compression=compression
-        )
-        compressed_file_path = (
-            f"{unique_filename}.{COMP_TO_EXT[compression]}"
-            if compression != "infer"
-            else unique_filename
-        )
+        with ensure_clean(".csv") as unique_filename:
+            make_csv_file(
+                filename=unique_filename, encoding=encoding, compression=compression
+            )
+            compressed_file_path = (
+                f"{unique_filename}.{COMP_TO_EXT[compression]}"
+                if compression != "infer"
+                else unique_filename
+            )
 
-        eval_io(
-            fn_name="read_csv",
-            # read_csv kwargs
-            filepath_or_buffer=compressed_file_path,
-            compression=compression,
-            encoding=encoding,
-            engine=engine,
-        )
+            eval_io(
+                fn_name="read_csv",
+                # read_csv kwargs
+                filepath_or_buffer=compressed_file_path,
+                compression=compression,
+                encoding=encoding,
+                engine=engine,
+            )
 
     @pytest.mark.parametrize(
         "encoding",
@@ -675,15 +676,15 @@ def test_read_csv_compression(self, make_csv_file, compression, encoding, engine
         ],
     )
     def test_read_csv_encoding(self, make_csv_file, encoding):
-        unique_filename = get_unique_filename()
-        make_csv_file(filename=unique_filename, encoding=encoding)
+        with ensure_clean(".csv") as unique_filename:
+            make_csv_file(filename=unique_filename, encoding=encoding)
 
-        eval_io(
-            fn_name="read_csv",
-            # read_csv kwargs
-            filepath_or_buffer=unique_filename,
-            encoding=encoding,
-        )
+            eval_io(
+                fn_name="read_csv",
+                # read_csv kwargs
+                filepath_or_buffer=unique_filename,
+                encoding=encoding,
+            )
 
     @pytest.mark.parametrize("thousands", [None, ",", "_", " "])
     @pytest.mark.parametrize("decimal", [".", "_"])
@@ -710,40 +711,40 @@ def test_read_csv_file_format(
                 "read_csv with Ray engine fails with `dialect` parameter - issue #2508"
             )
 
-        unique_filename = get_unique_filename()
-        if dialect:
-            test_csv_dialect_params = {
-                "delimiter": "_",
-                "doublequote": False,
-                "escapechar": "\\",
-                "quotechar": "d",
-                "quoting": csv.QUOTE_ALL,
-            }
-            csv.register_dialect(dialect, **test_csv_dialect_params)
-            dialect = csv.get_dialect(dialect)
-            make_csv_file(filename=unique_filename, **test_csv_dialect_params)
-        else:
-            make_csv_file(
-                filename=unique_filename,
-                thousands_separator=thousands,
-                decimal_separator=decimal,
+        with ensure_clean(".csv") as unique_filename:
+            if dialect:
+                test_csv_dialect_params = {
+                    "delimiter": "_",
+                    "doublequote": False,
+                    "escapechar": "\\",
+                    "quotechar": "d",
+                    "quoting": csv.QUOTE_ALL,
+                }
+                csv.register_dialect(dialect, **test_csv_dialect_params)
+                dialect = csv.get_dialect(dialect)
+                make_csv_file(filename=unique_filename, **test_csv_dialect_params)
+            else:
+                make_csv_file(
+                    filename=unique_filename,
+                    thousands_separator=thousands,
+                    decimal_separator=decimal,
+                    escapechar=escapechar,
+                    line_terminator=lineterminator,
+                )
+
+            eval_io(
+                check_exception_type=None,  # issue #2320
+                raising_exceptions=None,
+                fn_name="read_csv",
+                # read_csv kwargs
+                filepath_or_buffer=unique_filename,
+                thousands=thousands,
+                decimal=decimal,
+                lineterminator=lineterminator,
                 escapechar=escapechar,
-                line_terminator=lineterminator,
+                dialect=dialect,
             )
 
-        eval_io(
-            check_exception_type=None,  # issue #2320
-            raising_exceptions=None,
-            fn_name="read_csv",
-            # read_csv kwargs
-            filepath_or_buffer=unique_filename,
-            thousands=thousands,
-            decimal=decimal,
-            lineterminator=lineterminator,
-            escapechar=escapechar,
-            dialect=dialect,
-        )
-
     @pytest.mark.parametrize(
         "quoting",
         [csv.QUOTE_ALL, csv.QUOTE_MINIMAL, csv.QUOTE_NONNUMERIC, csv.QUOTE_NONE],
@@ -765,27 +766,26 @@ def test_read_csv_quoting(
             not doublequote and quotechar != '"' and quoting != csv.QUOTE_NONE
         )
         escapechar = "\\" if use_escapechar else None
-        unique_filename = get_unique_filename()
-
-        make_csv_file(
-            filename=unique_filename,
-            quoting=quoting,
-            quotechar=quotechar,
-            doublequote=doublequote,
-            escapechar=escapechar,
-            comment_col_char=comment,
-        )
+        with ensure_clean(".csv") as unique_filename:
+            make_csv_file(
+                filename=unique_filename,
+                quoting=quoting,
+                quotechar=quotechar,
+                doublequote=doublequote,
+                escapechar=escapechar,
+                comment_col_char=comment,
+            )
 
-        eval_io(
-            fn_name="read_csv",
-            # read_csv kwargs
-            filepath_or_buffer=unique_filename,
-            quoting=quoting,
-            quotechar=quotechar,
-            doublequote=doublequote,
-            escapechar=escapechar,
-            comment=comment,
-        )
+            eval_io(
+                fn_name="read_csv",
+                # read_csv kwargs
+                filepath_or_buffer=unique_filename,
+                quoting=quoting,
+                quotechar=quotechar,
+                doublequote=doublequote,
+                escapechar=escapechar,
+                comment=comment,
+            )
 
     # Error Handling parameters tests
     @pytest.mark.parametrize("warn_bad_lines", [True, False, None])
@@ -870,30 +870,29 @@ def test_read_csv_internal(
             "float_precision": float_precision,
         }
 
-        unique_filename = get_unique_filename()
-
-        if use_str_data:
-            str_delim_whitespaces = (
-                "col1 col2  col3   col4\n5 6   7  8\n9  10    11 12\n"
-            )
-            eval_io_from_str(
-                str_delim_whitespaces,
-                unique_filename,
-                raising_exceptions=raising_exceptions,
-                **kwargs,
-            )
-        else:
-            make_csv_file(
-                filename=unique_filename,
-                delimiter=delimiter,
-            )
+        with ensure_clean(".csv") as unique_filename:
+            if use_str_data:
+                str_delim_whitespaces = (
+                    "col1 col2  col3   col4\n5 6   7  8\n9  10    11 12\n"
+                )
+                eval_io_from_str(
+                    str_delim_whitespaces,
+                    unique_filename,
+                    raising_exceptions=raising_exceptions,
+                    **kwargs,
+                )
+            else:
+                make_csv_file(
+                    filename=unique_filename,
+                    delimiter=delimiter,
+                )
 
-            eval_io(
-                filepath_or_buffer=unique_filename,
-                fn_name="read_csv",
-                raising_exceptions=raising_exceptions,
-                **kwargs,
-            )
+                eval_io(
+                    filepath_or_buffer=unique_filename,
+                    fn_name="read_csv",
+                    raising_exceptions=raising_exceptions,
+                    **kwargs,
+                )
 
     # Issue related, specific or corner cases
     @pytest.mark.parametrize("nrows", [2, None])
@@ -902,9 +901,8 @@ def test_read_csv_bad_quotes(self, nrows):
             '1, 2, 3, 4\none, two, three, four\nfive, "six", seven, "eight\n'
         )
 
-        unique_filename = get_unique_filename()
-
-        eval_io_from_str(csv_bad_quotes, unique_filename, nrows=nrows)
+        with ensure_clean(".csv") as unique_filename:
+            eval_io_from_str(csv_bad_quotes, unique_filename, nrows=nrows)
 
     def test_read_csv_categories(self):
         eval_io(
@@ -1221,15 +1219,15 @@ def wrapped_read_csv(file, method):
     )
     @pytest.mark.parametrize("buffer_start_pos", [0, 10])
     def test_read_csv_file_handle(self, read_mode, make_csv_file, buffer_start_pos):
-        unique_filename = get_unique_filename()
-        make_csv_file(filename=unique_filename)
-
-        with open(unique_filename, mode=read_mode) as buffer:
-            buffer.seek(buffer_start_pos)
-            df_pandas = pandas.read_csv(buffer)
-            buffer.seek(buffer_start_pos)
-            df_modin = pd.read_csv(buffer)
-            df_equals(df_modin, df_pandas)
+        with ensure_clean() as unique_filename:
+            make_csv_file(filename=unique_filename)
+
+            with open(unique_filename, mode=read_mode) as buffer:
+                buffer.seek(buffer_start_pos)
+                df_pandas = pandas.read_csv(buffer)
+                buffer.seek(buffer_start_pos)
+                df_modin = pd.read_csv(buffer)
+        df_equals(df_modin, df_pandas)
 
     def test_unnamed_index(self):
         def get_internal_df(df):
@@ -1308,18 +1306,15 @@ def test_to_csv_with_index(self):
 
 class TestTable:
     def test_read_table(self, make_csv_file):
-        unique_filename = get_unique_filename()
-        make_csv_file(filename=unique_filename, delimiter="\t")
-        eval_io(
-            fn_name="read_table",
-            # read_table kwargs
-            filepath_or_buffer=unique_filename,
-        )
+        with ensure_clean() as unique_filename:
+            make_csv_file(filename=unique_filename, delimiter="\t")
+            eval_io(
+                fn_name="read_table",
+                # read_table kwargs
+                filepath_or_buffer=unique_filename,
+            )
 
     def test_read_table_within_decorator(self, make_csv_file):
-        unique_filename = get_unique_filename()
-        make_csv_file(filename=unique_filename, delimiter="\t")
-
         @dummy_decorator()
         def wrapped_read_table(file, method):
             if method == "pandas":
@@ -1328,22 +1323,25 @@ def wrapped_read_table(file, method):
             if method == "modin":
                 return pd.read_table(file)
 
-        pandas_df = wrapped_read_table(unique_filename, method="pandas")
-        modin_df = wrapped_read_table(unique_filename, method="modin")
+        with ensure_clean() as unique_filename:
+            make_csv_file(filename=unique_filename, delimiter="\t")
+
+            pandas_df = wrapped_read_table(unique_filename, method="pandas")
+            modin_df = wrapped_read_table(unique_filename, method="modin")
 
         df_equals(modin_df, pandas_df)
 
     def test_read_table_empty_frame(self, make_csv_file):
-        unique_filename = get_unique_filename()
-        make_csv_file(filename=unique_filename, delimiter="\t")
+        with ensure_clean() as unique_filename:
+            make_csv_file(filename=unique_filename, delimiter="\t")
 
-        eval_io(
-            fn_name="read_table",
-            # read_table kwargs
-            filepath_or_buffer=unique_filename,
-            usecols=["col1"],
-            index_col="col1",
-        )
+            eval_io(
+                fn_name="read_table",
+                # read_table kwargs
+                filepath_or_buffer=unique_filename,
+                usecols=["col1"],
+                index_col="col1",
+            )
 
 
 class TestParquet:
@@ -1358,16 +1356,17 @@ class TestParquet:
     def test_read_parquet(
         self, make_parquet_file, columns, row_group_size, engine, path_type
     ):
-        unique_filename = path_type(get_unique_filename(extension="parquet"))
-        make_parquet_file(filename=unique_filename, row_group_size=row_group_size)
+        with ensure_clean(".parquet") as unique_filename:
+            unique_filename = path_type(unique_filename)
+            make_parquet_file(filename=unique_filename, row_group_size=row_group_size)
 
-        eval_io(
-            fn_name="read_parquet",
-            # read_parquet kwargs
-            engine=engine,
-            path=unique_filename,
-            columns=columns,
-        )
+            eval_io(
+                fn_name="read_parquet",
+                # read_parquet kwargs
+                engine=engine,
+                path=unique_filename,
+                columns=columns,
+            )
 
     @pytest.mark.xfail(
         condition="config.getoption('--simulate-cloud').lower() != 'off'",
@@ -1381,10 +1380,11 @@ def test_read_parquet_indexing_by_column(self, make_parquet_file):
         nrows = (
             MinPartitionSize.get() + 1
         )  # Use the minimal guaranteed failing value for nrows.
-        unique_filename = get_unique_filename(extension="parquet")
-        make_parquet_file(filename=unique_filename, nrows=nrows)
+        with ensure_clean_dir() as dirname:
+            unique_filename = get_unique_filename(extension="parquet", data_dir=dirname)
+            make_parquet_file(filename=unique_filename, nrows=nrows)
 
-        parquet_df = pd.read_parquet(unique_filename)
+            parquet_df = pd.read_parquet(unique_filename)
         for col in parquet_df.columns:
             parquet_df[col]
 
@@ -1438,16 +1438,17 @@ def test_read_parquet_directory(
     def test_read_parquet_partitioned_directory(
         self, make_parquet_file, columns, engine
     ):
-        unique_filename = get_unique_filename(extension=None)
-        make_parquet_file(filename=unique_filename, partitioned_columns=["col1"])
+        with ensure_clean_dir() as dirname:
+            unique_filename = get_unique_filename(extension=None, data_dir=dirname)
+            make_parquet_file(filename=unique_filename, partitioned_columns=["col1"])
 
-        eval_io(
-            fn_name="read_parquet",
-            # read_parquet kwargs
-            engine=engine,
-            path=unique_filename,
-            columns=columns,
-        )
+            eval_io(
+                fn_name="read_parquet",
+                # read_parquet kwargs
+                engine=engine,
+                path=unique_filename,
+                columns=columns,
+            )
 
     @pytest.mark.parametrize("engine", ["pyarrow", "fastparquet"])
     @pytest.mark.xfail(
@@ -1456,7 +1457,6 @@ def test_read_parquet_partitioned_directory(
     )
     def test_read_parquet_pandas_index(self, engine):
         # Ensure modin can read parquet files written by pandas with a non-RangeIndex object
-        unique_filename = get_unique_filename(extension="parquet")
         pandas_df = pandas.DataFrame(
             {
                 "idx": np.random.randint(0, 100_000, size=2000),
@@ -1488,7 +1488,7 @@ def test_read_parquet_pandas_index(self, engine):
                 start="1/1/2018", periods=2000
             )
 
-        try:
+        with ensure_clean(".parquet") as unique_filename:
             for col in pandas_df.columns:
                 if col.startswith("idx"):
                     pandas_df.set_index(col).to_parquet(unique_filename)
@@ -1507,8 +1507,6 @@ def test_read_parquet_pandas_index(self, engine):
                 path=unique_filename,
                 engine=engine,
             )
-        finally:
-            os.remove(unique_filename)
 
     @pytest.mark.parametrize("engine", ["pyarrow", "fastparquet"])
     @pytest.mark.xfail(
@@ -1517,7 +1515,6 @@ def test_read_parquet_pandas_index(self, engine):
     )
     def test_read_parquet_pandas_index_partitioned(self, engine):
         # Ensure modin can read parquet files written by pandas with a non-RangeIndex object
-        unique_filename = get_unique_filename(extension="parquet")
         pandas_df = pandas.DataFrame(
             {
                 "idx": np.random.randint(0, 100_000, size=2000),
@@ -1526,7 +1523,8 @@ def test_read_parquet_pandas_index_partitioned(self, engine):
                 "C": ["c"] * 2000,
             }
         )
-        try:
+        with ensure_clean_dir() as dirname:
+            unique_filename = get_unique_filename(extension="parquet", data_dir=dirname)
             pandas_df.set_index("idx").to_parquet(unique_filename, partition_cols=["A"])
             # read the same parquet using modin.pandas
             eval_io(
@@ -1535,8 +1533,6 @@ def test_read_parquet_pandas_index_partitioned(self, engine):
                 path=unique_filename,
                 engine=engine,
             )
-        finally:
-            shutil.rmtree(unique_filename)
 
     @pytest.mark.parametrize("engine", ["pyarrow", "fastparquet"])
     @pytest.mark.xfail(
@@ -1587,17 +1583,17 @@ def test_read_parquet_without_metadata(self, engine):
         from pyarrow import csv
         from pyarrow import parquet
 
-        parquet_fname = get_unique_filename(extension="parquet")
-        csv_fname = get_unique_filename(extension="parquet")
-        pandas_df = pandas.DataFrame(
-            {
-                "idx": np.random.randint(0, 100_000, size=2000),
-                "A": np.random.randint(0, 10, size=2000),
-                "B": ["a", "b"] * 1000,
-                "C": ["c"] * 2000,
-            }
-        )
-        try:
+        with ensure_clean_dir() as dirname:
+            parquet_fname = get_unique_filename(extension="parquet", data_dir=dirname)
+            csv_fname = get_unique_filename(extension="parquet", data_dir=dirname)
+            pandas_df = pandas.DataFrame(
+                {
+                    "idx": np.random.randint(0, 100_000, size=2000),
+                    "A": np.random.randint(0, 10, size=2000),
+                    "B": ["a", "b"] * 1000,
+                    "C": ["c"] * 2000,
+                }
+            )
             pandas_df.to_csv(csv_fname, index=False)
             # read into pyarrow table and write it to a parquet file
             t = csv.read_csv(csv_fname)
@@ -1609,8 +1605,6 @@ def test_read_parquet_without_metadata(self, engine):
                 path=parquet_fname,
                 engine=engine,
             )
-        finally:
-            teardown_test_files([parquet_fname, csv_fname])
 
     @pytest.mark.parametrize("engine", ["pyarrow", "fastparquet"])
     def test_read_empty_parquet_file(self, engine):
@@ -1904,12 +1898,13 @@ def test_ExcelFile(self, make_excel_file):
     def test_to_excel(self):
         modin_df, pandas_df = create_test_dfs(TEST_DATA)
 
-        unique_filename_modin = get_unique_filename(extension="xlsx")
-        unique_filename_pandas = get_unique_filename(extension="xlsx")
+        with ensure_clean_dir() as dir:
+            unique_filename_modin = get_unique_filename(extension="xlsx", data_dir=dir)
+            unique_filename_pandas = get_unique_filename(extension="xlsx", data_dir=dir)
+
+            modin_writer = pandas.ExcelWriter(unique_filename_modin)
+            pandas_writer = pandas.ExcelWriter(unique_filename_pandas)
 
-        modin_writer = pandas.ExcelWriter(unique_filename_modin)
-        pandas_writer = pandas.ExcelWriter(unique_filename_pandas)
-        try:
             modin_df.to_excel(modin_writer)
             pandas_df.to_excel(pandas_writer)
 
@@ -1917,8 +1912,6 @@ def test_to_excel(self):
             pandas_writer.save()
 
             assert assert_files_eq(unique_filename_modin, unique_filename_pandas)
-        finally:
-            teardown_test_files([unique_filename_modin, unique_filename_pandas])
 
     @pytest.mark.xfail(
         Engine.get() != "Python"
@@ -1961,9 +1954,14 @@ def test_read_hdf(self, make_hdf_file, format):
     )
     def test_HDFStore(self):
         hdf_file = None
-        unique_filename_modin = get_unique_filename(extension="hdf")
-        unique_filename_pandas = get_unique_filename(extension="hdf")
-        try:
+        with ensure_clean_dir() as dirname:
+            unique_filename_modin = get_unique_filename(
+                extension="hdf", data_dir=dirname
+            )
+            unique_filename_pandas = get_unique_filename(
+                extension="hdf", data_dir=dirname
+            )
+
             modin_store = pd.HDFStore(unique_filename_modin)
             pandas_store = pandas.HDFStore(unique_filename_pandas)
 
@@ -1983,37 +1981,29 @@ def test_HDFStore(self):
             df_equals(modin_df, pandas_df)
             assert isinstance(modin_store, pd.HDFStore)
 
-            handle, hdf_file = tempfile.mkstemp(suffix=".hdf5", prefix="test_read")
-            os.close(handle)
+        with ensure_clean(".hdf5") as hdf_file:
             with pd.HDFStore(hdf_file, mode="w") as store:
                 store.append("data/df1", pd.DataFrame(np.random.randn(5, 5)))
                 store.append("data/df2", pd.DataFrame(np.random.randn(4, 4)))
 
             modin_df = pd.read_hdf(hdf_file, key="data/df1", mode="r")
             pandas_df = pandas.read_hdf(hdf_file, key="data/df1", mode="r")
-            df_equals(modin_df, pandas_df)
-        finally:
-            if hdf_file:
-                os.unlink(hdf_file)
-            teardown_test_files([unique_filename_modin, unique_filename_pandas])
+        df_equals(modin_df, pandas_df)
 
     @pytest.mark.xfail(
         condition="config.getoption('--simulate-cloud').lower() != 'off'",
         reason="The reason of tests fail in `cloud` mode is unknown for now - issue #3264",
     )
     def test_HDFStore_in_read_hdf(self):
-        filename = get_unique_filename(extension="hdf")
-        dfin = pd.DataFrame(np.random.rand(8, 8))
-        try:
+        with ensure_clean(".hdf") as filename:
+            dfin = pd.DataFrame(np.random.rand(8, 8))
             dfin.to_hdf(filename, "/key")
 
             with pd.HDFStore(filename) as h:
                 modin_df = pd.read_hdf(h, "/key")
             with pandas.HDFStore(filename) as h:
                 pandas_df = pandas.read_hdf(h, "/key")
-            df_equals(modin_df, pandas_df)
-        finally:
-            teardown_test_files([filename])
+        df_equals(modin_df, pandas_df)
 
 
 class TestSql:
@@ -2023,58 +2013,59 @@ class TestSql:
     )
     @pytest.mark.parametrize("read_sql_engine", ["Pandas", "Connectorx"])
     def test_read_sql(self, make_sql_connection, read_sql_engine):
-        filename = get_unique_filename(extension="db")
-        table = "test_read_sql"
-        conn = make_sql_connection(filename, table)
-        query = f"select * from {table}"
+        with ensure_clean_dir() as dirname:
+            filename = get_unique_filename(".db")
+            table = "test_read_sql"
+            conn = make_sql_connection(os.path.join(dirname, filename), table)
+            query = f"select * from {table}"
 
-        eval_io(
-            fn_name="read_sql",
-            # read_sql kwargs
-            sql=query,
-            con=conn,
-        )
-
-        eval_io(
-            fn_name="read_sql",
-            # read_sql kwargs
-            sql=query,
-            con=conn,
-            index_col="index",
-        )
+            eval_io(
+                fn_name="read_sql",
+                # read_sql kwargs
+                sql=query,
+                con=conn,
+            )
 
-        with warns_that_defaulting_to_pandas():
-            pd.read_sql_query(query, conn)
+            eval_io(
+                fn_name="read_sql",
+                # read_sql kwargs
+                sql=query,
+                con=conn,
+                index_col="index",
+            )
 
-        with warns_that_defaulting_to_pandas():
-            pd.read_sql_table(table, conn)
+            with warns_that_defaulting_to_pandas():
+                pd.read_sql_query(query, conn)
 
-        # Test SQLAlchemy engine
-        sqlalchemy_engine = sa.create_engine(conn)
-        eval_io(
-            fn_name="read_sql",
-            # read_sql kwargs
-            sql=query,
-            con=sqlalchemy_engine,
-        )
+            with warns_that_defaulting_to_pandas():
+                pd.read_sql_table(table, conn)
 
-        # Test SQLAlchemy Connection
-        sqlalchemy_connection = sqlalchemy_engine.connect()
-        eval_io(
-            fn_name="read_sql",
-            # read_sql kwargs
-            sql=query,
-            con=sqlalchemy_connection,
-        )
+            # Test SQLAlchemy engine
+            sqlalchemy_engine = sa.create_engine(conn)
+            eval_io(
+                fn_name="read_sql",
+                # read_sql kwargs
+                sql=query,
+                con=sqlalchemy_engine,
+            )
 
-        ReadSqlEngine.put(read_sql_engine)
-        if ReadSqlEngine.get() == "Connectorx":
-            modin_df = pd.read_sql(sql=query, con=conn)
-        else:
-            modin_df = pd.read_sql(
-                sql=query, con=ModinDatabaseConnection("sqlalchemy", conn)
+            # Test SQLAlchemy Connection
+            sqlalchemy_connection = sqlalchemy_engine.connect()
+            eval_io(
+                fn_name="read_sql",
+                # read_sql kwargs
+                sql=query,
+                con=sqlalchemy_connection,
             )
-        pandas_df = pandas.read_sql(sql=query, con=sqlalchemy_connection)
+
+            ReadSqlEngine.put(read_sql_engine)
+            if ReadSqlEngine.get() == "Connectorx":
+                modin_df = pd.read_sql(sql=query, con=conn)
+            else:
+                modin_df = pd.read_sql(
+                    sql=query, con=ModinDatabaseConnection("sqlalchemy", conn)
+                )
+            pandas_df = pandas.read_sql(sql=query, con=sqlalchemy_connection)
         df_equals(modin_df, pandas_df)
 
     @pytest.mark.skipif(
@@ -2147,21 +2138,22 @@ def test_to_sql(self, make_sql_connection, index):
         table_name = f"test_to_sql_{str(index)}"
         modin_df, pandas_df = create_test_dfs(TEST_DATA)
 
-        # We do not pass the table name so the fixture won't generate a table
-        conn = make_sql_connection(f"{table_name}_modin.db")
-        modin_df.to_sql(table_name, conn, index=index)
-        df_modin_sql = pandas.read_sql(
-            table_name, con=conn, index_col="index" if index else None
-        )
+        with ensure_clean_dir() as dirname:
+            # We do not pass the table name so the fixture won't generate a table
+            conn = make_sql_connection(os.path.join(dirname, f"{table_name}_modin.db"))
+            modin_df.to_sql(table_name, conn, index=index)
+            df_modin_sql = pandas.read_sql(
+                table_name, con=conn, index_col="index" if index else None
+            )
 
-        # We do not pass the table name so the fixture won't generate a table
-        conn = make_sql_connection(f"{table_name}_pandas.db")
-        pandas_df.to_sql(table_name, conn, index=index)
-        df_pandas_sql = pandas.read_sql(
-            table_name, con=conn, index_col="index" if index else None
-        )
+            # We do not pass the table name so the fixture won't generate a table
+            conn = make_sql_connection(os.path.join(dirname, f"{table_name}_pandas.db"))
+            pandas_df.to_sql(table_name, conn, index=index)
+            df_pandas_sql = pandas.read_sql(
+                table_name, con=conn, index_col="index" if index else None
+            )
 
-        assert df_modin_sql.sort_index().equals(df_pandas_sql.sort_index())
+            assert df_modin_sql.sort_index().equals(df_pandas_sql.sort_index())
 
 
 class TestHtml:
@@ -2520,16 +2512,17 @@ def test_to_pickle(self):
         eval_to_file(
             modin_obj=modin_df, pandas_obj=pandas_df, fn="to_pickle", extension="pkl"
         )
-
-        unique_filename_modin = get_unique_filename(extension="pkl")
-        unique_filename_pandas = get_unique_filename(extension="pkl")
-        try:
+        with ensure_clean_dir() as dirname:
+            unique_filename_modin = get_unique_filename(
+                extension="pkl", data_dir=dirname
+            )
+            unique_filename_pandas = get_unique_filename(
+                extension="pkl", data_dir=dirname
+            )
             pd.to_pickle(modin_df, unique_filename_modin)
             pandas.to_pickle(pandas_df, unique_filename_pandas)
 
             assert assert_files_eq(unique_filename_modin, unique_filename_pandas)
-        finally:
-            teardown_test_files([unique_filename_modin, unique_filename_pandas])
 
 
 @pytest.mark.xfail(
diff --git a/modin/pandas/test/utils.py b/modin/pandas/test/utils.py
--- a/modin/pandas/test/utils.py
+++ b/modin/pandas/test/utils.py
@@ -55,9 +55,6 @@
 RAND_LOW = 0
 RAND_HIGH = 100
 
-# Directory for storing I/O operations test data
-IO_OPS_DATA_DIR = os.path.join(os.path.dirname(__file__), "io_tests_data")
-
 # Input data and functions for the tests
 # The test data that we will test our code against
 test_data = {
@@ -978,7 +975,7 @@ def get_unique_filename(
     test_name: str = "test",
     kwargs: dict = {},
     extension: str = "csv",
-    data_dir: str = IO_OPS_DATA_DIR,
+    data_dir: str = "",
     suffix: str = "",
     debug_mode=False,
 ):