code: def test_unpartitioned_complement_access_transformer(self):
      df = (
          self.create_dataframe()
          .filter(f.col("tenant") == "t1")
          .select("user", "res")
          .cache()
      )
      assert df is not None and df.count() > 0
  
      transformer = ComplementAccessTransformer(
          None, ["user", "res"], 3
      )
      complement_df = transformer.transform(df).cache()
      assert complement_df is not None and complement_df.count() > 0
      assert complement_df.schema == df.schema
  
      assert (
          complement_df.select("user", "res").distinct().count()
          == complement_df.count()
      )
      assert complement_df.join(df, ["user", "res"]).count() == 0
  
      assert (
          complement_df.agg(f.max("user").alias("max_user")).first()[
              "max_user"
          ]
          <= 5
      )
      assert (
          complement_df.agg(f.max("res").alias("max_res")).first()[
              "max_res"
          ]
          <= 5
      )
  
file_path: SynapseML/core/src/test/python/synapsemltest/cyber/anamoly/test_complement_access.py
imports: import unittest
  from typing import Type
  from pyspark.sql import DataFrame, types, functions
  from synapse.ml.cyber.anomaly.complement_access import ComplementAccessTransformer
  from synapsemltest.cyber.explain_tester import ExplainTester
  from synapsemltest.spark import *
label_desc: Use image node_id 3 for calling the TestComplementAccessTransformer obj's underlying member method code with example usage: obj.test_unpartitioned_complement_access_transformer() without return types