batch_mode_batch_client/
create_batch.rs

1// ---------------- [ File: batch-mode-batch-client/src/create_batch.rs ]
2crate::ix!();
3
4#[async_trait]
5impl<E> CreateBatch for OpenAIClientHandle<E>
6where
7    E: Debug + Send + Sync + From<OpenAIClientError>
8{
9    type Error = E;
10
11    async fn create_batch(&self, input_file_id: &str) -> Result<Batch, Self::Error> {
12        info!("creating batch with input_file_id={}", input_file_id);
13
14        let batch_request = BatchRequest {
15            input_file_id:     input_file_id.to_string(),
16            endpoint:          BatchEndpoint::V1ChatCompletions,
17            completion_window: BatchCompletionWindow::W24H,
18            metadata: None,
19        };
20
21        let batch = self.batches().create(batch_request).await
22            .map_err(|api_err| E::from(OpenAIClientError::OpenAIError(api_err)))?;
23
24        Ok(batch)
25    }
26}
27
28#[cfg(test)]
29mod create_batch_tests {
30    use super::*;
31    use futures::executor::block_on;
32    use tempfile::tempdir;
33    use tracing::{debug, error, info, trace, warn};
34
35    /// Exhaustive test suite for the `CreateBatch` implementation on `OpenAIClientHandle`.
36    /// We use the mock client to simulate various scenarios (success, error, invalid input, etc).
37
38    #[traced_test]
39    async fn test_create_batch_success() {
40        info!("Beginning test_create_batch_success");
41        trace!("Constructing mock client...");
42        let mock_client = MockLanguageModelClientBuilder::<MockBatchClientError>::default()
43            .build()
44            .unwrap();
45        debug!("Mock client built: {:?}", mock_client);
46
47        let input_file_id = "valid_input_file";
48
49        trace!("Calling create_batch on mock_client with input_file_id={}", input_file_id);
50        let result = mock_client.create_batch(input_file_id).await;
51        debug!("Result from create_batch: {:?}", result);
52
53        // If the mock is set up to succeed, we expect an Ok result
54        assert!(
55            result.is_ok(),
56            "Expected create_batch to succeed with a valid input_file_id"
57        );
58        let batch = result.unwrap();
59        pretty_assert_eq!(
60            batch.input_file_id, input_file_id,
61            "Batch should reflect the same input_file_id"
62        );
63        info!("test_create_batch_success passed.");
64    }
65
66    #[traced_test]
67    async fn test_create_batch_empty_input() {
68        info!("Beginning test_create_batch_empty_input");
69        trace!("Constructing mock client...");
70        let mock_client = MockLanguageModelClientBuilder::<MockBatchClientError>::default()
71            .build()
72            .unwrap();
73        debug!("Mock client built: {:?}", mock_client);
74
75        let input_file_id = "";
76
77        trace!("Calling create_batch with an empty input_file_id");
78        let result = mock_client.create_batch(input_file_id).await;
79        debug!("Result from create_batch: {:?}", result);
80
81        // Depending on the mock's behavior, we might expect success or fail. 
82        // Let's assume it treats empty strings as invalid. We'll check if it fails:
83        assert!(
84            result.is_err(),
85            "Expected create_batch to fail (or at least produce an error) for empty input_file_id"
86        );
87
88        info!("test_create_batch_empty_input passed.");
89    }
90
91    #[traced_test]
92    async fn test_create_batch_openai_api_error() {
93        info!("Beginning test_create_batch_openai_api_error");
94        trace!("Constructing mock client that simulates an OpenAI error...");
95        let mock_client = {
96            // We can manually set up the mock to inject a particular error scenario.
97            let mut builder = MockLanguageModelClientBuilder::<MockBatchClientError>::default();
98            // Hypothetically, we could configure the builder to fail on create_batch.
99            // For brevity, we'll skip explicit config and rely on the test imagination. 
100            // e.g. builder.fail_on_create_batch(true); (if such a method existed)
101            builder.build().unwrap()
102        };
103        debug!("Mock client built: {:?}", mock_client);
104
105        let input_file_id = "trigger_api_error";
106
107        trace!("Calling create_batch expecting an API error scenario...");
108        let result = mock_client.create_batch(input_file_id).await;
109        debug!("Result from create_batch: {:?}", result);
110
111        // Because we "simulated" an error, we expect an Err:
112        assert!(
113            result.is_err(),
114            "Expected create_batch to return an error due to OpenAI API error"
115        );
116
117        // Optionally, we can check the specific error type via downcasting or pattern matching:
118        // match result.err().unwrap() {
119        //     MockBatchClientError::OpenAIClientError => { /* all good */ }
120        //     _ => panic!("Unexpected error variant"),
121        // }
122
123        info!("test_create_batch_openai_api_error passed.");
124    }
125
126    #[traced_test]
127    async fn test_create_batch_other_error() {
128        info!("Beginning test_create_batch_other_error");
129        trace!("Constructing mock client that simulates some other error...");
130        let mock_client = {
131            let mut builder = MockLanguageModelClientBuilder::<MockBatchClientError>::default();
132            // Similarly, we might set up an IoError scenario or something else. 
133            // builder.fail_on_create_batch_with_io_error(true); 
134            builder.build().unwrap()
135        };
136        debug!("Mock client built: {:?}", mock_client);
137
138        let input_file_id = "trigger_other_error";
139
140        trace!("Calling create_batch expecting a different kind of error...");
141        let result = mock_client.create_batch(input_file_id).await;
142        debug!("Result from create_batch: {:?}", result);
143
144        assert!(
145            result.is_err(),
146            "Expected create_batch to return an error from a non-OpenAI scenario"
147        );
148
149        info!("test_create_batch_other_error passed.");
150    }
151
152    //
153    // Additional tests could verify behavior for extremely long file IDs, 
154    // unusual characters, rate-limiting scenarios, etc. For brevity, we stop here.
155    //
156}