def METHOD_NAME(
    tensor_shape, rank, ls_solve, random_state, er_decrease_tol, monkeypatch
):
    rng = tl.check_random_state(random_state)
    # Generate random tensor which has exact tensor ring decomposition
    tensor = random_tr(
        tensor_shape, rank, full=True, random_state=rng, dtype=tl.float64
    )
    # Ensure ValueError is raised for when invalid ls_solve is given
    with np.testing.assert_raises(ValueError):
        tr_decomp = tensor_ring_als(
            tensor, rank, random_state=rng, ls_solve="invalid_ls_solve"
        )
    # Create callback function for error tracking and run decomposition
    callback = ErrorTracker()
    tr_decomp = tensor_ring_als(
        tensor, rank, random_state=rng, callback=callback, ls_solve=ls_solve
    )
    # Ensure decomposition returns right number of factors
    assert_(len(tr_decomp.factors) == len(tensor_shape))
    # Ensure cores are sized correctly
    for i in range(len(tensor_shape)):
        core_shape = tr_decomp[i].shape
        assert_(core_shape[0] == rank[i])
        assert_(core_shape[1] == tensor_shape[i])
        assert_(core_shape[2] == rank[i + 1])
    # Compute decomposition relative error and ensure it's small enough
    rel_error_tol = 1e-2
    rel_error = tl.norm(tl.tr_to_tensor(tr_decomp) - tensor) / tl.norm(tensor)
    assert_(rel_error < rel_error_tol)
    # Ensure error decreases monotonically (up to numerical error)
    for i in range(len(callback.error) - 1):
        assert_(callback.error[i + 1] < callback.error[i] + er_decrease_tol)
    # Ensure TensorRingALS class passes arguments correctly to decomposition function
    assert_class_wrapper_correctly_passes_arguments(
        monkeypatch, tensor_ring_als, TensorRingALS, rank=3
    )
    # Ensure that the computed decomposition is the same when the same random seed is
    # used
    rng1 = tl.check_random_state(random_state)
    rng2 = tl.check_random_state(random_state)
    callback1 = ErrorTracker()
    callback2 = ErrorTracker()
    tr_decomp1 = tensor_ring_als(
        tensor, rank, random_state=rng1, callback=callback1, ls_solve=ls_solve
    )
    tr_decomp2 = tensor_ring_als(
        tensor, rank, random_state=rng2, callback=callback2, ls_solve=ls_solve
    )
    assert_array_almost_equal(callback1.error, callback2.error)
    for i in range(len(tr_decomp1.factors)):
        assert_array_almost_equal(tr_decomp1[i], tr_decomp2[i])