def test_llmcompletion(self):
        """Check that LLMProvider feedback functions produce a value in the 0-1
        range only.

        Also check to make sure chain of thought reasons feedback functions
        produce criteria and supporting evidence. Only checks each feedback
        function once for each model.
        """

        models = ["gpt-3.5-turbo"]
        provider_models = [
            (openai_provider.OpenAI(model_engine=model), model)
            for model in models
        ]
        for provider, model in provider_models:
            with self.subTest(f"{provider.__class__.__name__}-{model}"):
                tests = get_llmprovider_tests(provider)
                funcs = set()

                for imp, args, _ in tests:
                    # only one test per feedback function per model:
                    if (imp, model) in funcs:
                        continue
                    funcs.add((imp, model))

                    with self.subTest(f"{imp.__name__}-{model}-{args}"):
                        if "with_cot_reasons" in imp.__name__:
                            result = imp(**args)
                            self.assertIsInstance(
                                result, tuple, "Result should be a tuple."
                            )
                            self.assertEqual(
                                len(result),
                                2,
                                "Tuple should have two elements.",
                            )
                            score, details = result
                            self.assertIsInstance(
                                score,
                                float,
                                "First element of tuple should be a float.",
                            )
                            self.assertGreaterEqual(
                                score,
                                0.0,
                                "First element of tuple should be greater than or equal to 0.0.",
                            )
                            self.assertLessEqual(
                                score,
                                1.0,
                                "First element of tuple should be less than or equal to 1.0.",
                            )
                            self.assertIsInstance(
                                details,
                                dict,
                                "Second element of tuple should be a dict.",
                            )
                            self.assertIn(
                                "reason",
                                details,
                                "Dict should contain the key 'reason'.",
                            )
                            reason_text = details.get("reason", "")
                            self.assertIn(
                                "Criteria:",
                                reason_text,
                                "The 'reason' text should include the string 'Criteria:'.",
                            )
                            self.assertIn(
                                "Supporting Evidence:",
                                reason_text,
                                "The 'reason' text should include the string 'Supporting Evidence:'.",
                            )
                            criteria_index = reason_text.find(
                                "Criteria:"
                            ) + len("Criteria:")
                            supporting_evidence_index = reason_text.find(
                                "Supporting Evidence:"
                            )
                            criteria_content = reason_text[
                                criteria_index:supporting_evidence_index
                            ].strip()
                            supporting_evidence_index = reason_text.find(
                                "Supporting Evidence:"
                            ) + len("Supporting Evidence:")
                            supporting_evidence_content = reason_text[
                                supporting_evidence_index:
                            ].strip()
                            self.assertNotEqual(
                                criteria_content,
                                "",
                                "There should be text following 'Criteria:'.",
                            )
                            self.assertNotEqual(
                                supporting_evidence_content,
                                "",
                                "There should be text following 'Supporting Evidence:'.",
                            )
                        else:
                            actual = imp(**args)
                            self.assertGreaterEqual(
                                actual,
                                0.0,
                                "First element of tuple should be greater than or equal to 0.0.",
                            )
                            self.assertLessEqual(
                                actual,
                                1.0,
                                "First element of tuple should be less than or equal to 1.0.",
                            )
Check that LLMProvider feedback functions produce a value in the 0-1
        range only.

        Also check to make sure chain of thought reasons feedback functions
        produce criteria and supporting evidence. Only checks each feedback
        function once for each model.
        
tests/e2e/test_providers.py