API
 
Loading...
Searching...
No Matches
streamWriter_test.cpp
Go to the documentation of this file.
1
2#include "../../../tests/catch2/catch.hpp"
3#include "../../tests/testMacrosINDI.hpp"
4
5#include "../streamWriter.hpp"
6
7using namespace MagAOX::app;
8
9namespace MagAOX
10{
11namespace app
12{
13
14//Standard test harness for INDI callbacks
16{
18
19 streamWriter_test(const std::string & device)
20 {
21 m_configName = device;
22 m_outName = device;
23
25 }
26
27
28};
29
30//Test harness for data writing
32{
34
39
40 std::string rawimageDir()
41 {
42 return m_sw->m_rawimageDir;
43 }
44
45 int setup_circbufs( int width, int height, int dataType, int circBuffLength, int writeChunkLength )
46 {
47 m_sw->m_typeSize = ImageStreamIO_typesize( dataType );
48
49 m_sw->m_maxCircBuffLength = circBuffLength;
50 m_sw->m_maxCircBuffSize = ( width * height * m_sw->m_typeSize * circBuffLength + 1 ) / 1048576.0;
51 m_sw->m_maxWriteChunkLength = writeChunkLength;
52
53 m_sw->m_width = width;
54 m_sw->m_height = height;
55 m_sw->m_dataType = dataType;
56
57 return m_sw->allocate_circbufs();
58 }
59
60 // Sets m_writeChunkLength and calls allocate_xrif
61 // Call this *only* after setup_circbufs.
63 {
64
66 return m_sw->allocate_xrif();
67 }
68
69 // Fill the circular buffers.
71 {
72 // fill in image data with increasing 256 bit vals.
73 for( size_t pp = 0; pp < m_sw->m_circBuffLength; ++pp )
74 {
75 uint16_t v = pp;
76 for( size_t rr = 0; rr < m_sw->m_width; ++rr )
77 {
78 for( size_t cc = 0; cc < m_sw->m_height; ++cc )
79 {
80 ( (uint16_t *)
81 m_sw->m_rawImageCircBuff )[pp * m_sw->m_width * m_sw->m_height + rr * m_sw->m_height + cc] =
82 v;
83 ++v;
84 }
85 }
86
87 // fitsFile<uint16_t> ff;
88 // ff.write("cb.fits", m_sw->m_rawImageCircBuff);
89
90 // Fill in timing values with unique vals.
91 uint64_t *curr_timing = m_sw->m_timingCircBuff + 5 * pp;
92 curr_timing[0] = pp; // image number
93 curr_timing[1] = pp + 1000; // atime sec
94 curr_timing[2] = pp + 2000; // atime nsec
95 curr_timing[3] = pp + m_sw->m_circBuffLength + 1000; // wtime sec
96 curr_timing[4] = pp + m_sw->m_circBuffLength + 2000; // wtime nsec
97 }
98 return 0;
99 }
100
101 int write_frames( int start, // arbitrary.
102 int stop // should be a m_writeChunkLength boundary
103 )
104 {
105 m_sw->m_rawimageDir = "/tmp";
106
107 m_sw->m_currSaveStart = start;
108 m_sw->m_currSaveStop = stop;
110
112 return m_sw->doEncode();
113 }
114
115 // Read the xrif archive back in and compare the results.
116 int comp_frames_uint16( size_t start, size_t stop )
117 {
118
119 std::cout << "Reading: " << m_sw->m_outFilePath << "\n";
120
121 xrif_t xrif;
122 xrif_error_t xrv = xrif_new( &xrif );
123
124 char header[XRIF_HEADER_SIZE];
125
126 FILE *fp_xrif = fopen( m_sw->m_outFilePath.c_str(), "rb" );
127 size_t nr = fread( header, 1, XRIF_HEADER_SIZE, fp_xrif );
128
129 if( nr != XRIF_HEADER_SIZE )
130 {
131 std::cerr << "Error reading header of " << m_sw->m_outFilePath << "\n";
132 fclose( fp_xrif );
133 return -1;
134 }
135
136 uint32_t header_size;
137 xrif_read_header( xrif, &header_size, header );
138
139 int rv = 0;
140 if( xrif_width( xrif ) != m_sw->m_width )
141 {
142 std::cerr << "width mismatch\n";
143 rv = -1;
144 }
145
146 if( xrif_height( xrif ) != m_sw->m_height )
147 {
148 std::cerr << "height mismatch\n";
149 rv = -1;
150 }
151
152 if( xrif_depth( xrif ) != 1 )
153 {
154 std::cerr << "depth mismatch\n";
155 rv = -1;
156 }
157
158 if( xrif_frames( xrif ) != stop - start )
159 {
160 std::cerr << "frames mismatch\n";
161 rv = -1;
162 }
163
164 xrif_allocate( xrif );
165
166 nr = fread( xrif->raw_buffer, 1, xrif->compressed_size, fp_xrif );
167
168 if( nr != xrif->compressed_size )
169 {
170 std::cerr << "error reading compressed image buffer.\n";
171 return -1;
172 }
173
174 xrv = xrif_decode( xrif );
175 if( xrv != XRIF_NOERROR )
176 {
177 std::cerr << "error decoding compressed image buffer. Code: " << xrv << "\n";
178 return -1;
179 }
180
181 size_t badpix = 0;
182
183 for( size_t n = 0; n < m_sw->m_width * m_sw->m_height * m_sw->m_typeSize * ( stop - start ); ++n )
184 {
185 if( m_sw->m_rawImageCircBuff[start * m_sw->m_width * m_sw->m_height * m_sw->m_typeSize + n] !=
186 xrif->raw_buffer[n] )
187 ++badpix;
188 }
189
190 if( badpix > 0 )
191 {
192 std::cerr << "Buffers don't match: " << badpix << " bad pixels.\n";
193 return -1;
194 }
195
196 return rv;
197 }
198};
199} // namespace app
200} // namespace MagAOX
201
202using namespace MagAOX::app;
203
204SCENARIO( "streamWriter INDI Callbacks", "[streamWriter]" )
205{
207}
208
209SCENARIO( "streamWriter Configuration", "[streamWriter]" )
210{
211 GIVEN( "A default constructed streamWriter" )
212 {
213 streamWriter_test sw("testdev");
214 streamWriter_data_test sw_test( &sw );
215
216 WHEN( "default configurations" )
217 {
218 REQUIRE( sw_test.rawimageDir() == "" );
219 }
220 }
221}
222
223SCENARIO( "streamWriter encoding data", "[streamWriter]" )
224{
225 GIVEN( "A default constructed streamWriter and a 120x120 uint16 stream" )
226 {
227 streamWriter_test sw("testdev");
228 streamWriter_data_test sw_test( &sw );
229
230 WHEN( "writing full 1st chunk" )
231 {
232 int circBuffLength = 10;
233 int writeChunkLength = 5;
234 REQUIRE( sw_test.setup_circbufs( 120, 120, XRIF_TYPECODE_UINT16, circBuffLength, writeChunkLength ) == 0 );
235 REQUIRE( sw_test.setup_xrif() == 0 );
236
237 REQUIRE( sw_test.fill_circbuf_uint16() == 0 );
238
239 REQUIRE( sw_test.write_frames( 0, 5 ) == 0 );
240
241 REQUIRE( sw_test.comp_frames_uint16( 0, 5 ) == 0 );
242 }
243
244 WHEN( "writing full 2nd chunk" )
245 {
246 int circBuffLength = 10;
247 int writeChunkLength = 5;
248 REQUIRE( sw_test.setup_circbufs( 120, 120, XRIF_TYPECODE_UINT16, circBuffLength, writeChunkLength ) == 0 );
249 REQUIRE( sw_test.setup_xrif() == 0 );
250 //REQUIRE( sw_test.setup_fname() == 0 );
251
252 REQUIRE( sw_test.fill_circbuf_uint16() == 0 );
253
254 REQUIRE( sw_test.write_frames( 5, 10 ) == 0 );
255
256 REQUIRE( sw_test.comp_frames_uint16( 5, 10 ) == 0 );
257 }
258
259 WHEN( "writing partial 1st chunk" )
260 {
261 int circBuffLength = 10;
262 int writeChunkLength = 5;
263 REQUIRE( sw_test.setup_circbufs( 120, 120, XRIF_TYPECODE_UINT16, circBuffLength, writeChunkLength ) == 0 );
264 REQUIRE( sw_test.setup_xrif() == 0 );
265 //REQUIRE( sw_test.setup_fname() == 0 );
266
267 REQUIRE( sw_test.fill_circbuf_uint16() == 0 );
268
269 REQUIRE( sw_test.write_frames( 2, 5 ) == 0 );
270
271 REQUIRE( sw_test.comp_frames_uint16( 2, 5 ) == 0 );
272 }
273
274 WHEN( "writing partial 2nd chunk" )
275 {
276 int circBuffLength = 10;
277 int writeChunkLength = 5;
278 REQUIRE( sw_test.setup_circbufs( 120, 120, XRIF_TYPECODE_UINT16, circBuffLength, writeChunkLength ) == 0 );
279 REQUIRE( sw_test.setup_xrif() == 0 );
280 //REQUIRE( sw_test.setup_fname() == 0 );
281
282 REQUIRE( sw_test.fill_circbuf_uint16() == 0 );
283
284 REQUIRE( sw_test.write_frames( 5, 8 ) == 0 );
285
286 REQUIRE( sw_test.comp_frames_uint16( 5, 8 ) == 0 );
287 }
288 }
289}
std::string m_configName
The name of the configuration file (minus .conf).
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
size_t m_circBuffLength
The length of the circular buffer, in frames.
int initialize_xrif()
Initialize the xrif system.
uint8_t m_dataType
The ImageStreamIO type code.
int m_typeSize
The pixel byte depth.
uint64_t m_currSaveStart
The circular buffer position at which to start saving.
size_t m_height
The height of the image.
uint64_t m_currSaveStopFrameNo
The frame number of the image at which saving stopped (for logging)
int allocate_circbufs()
Worker function to allocate the circular buffers.
std::string m_outName
The name to use for outputting files, Default is m_shmimName.
size_t m_maxCircBuffLength
The maximum length of the circular buffer, in frames.
int allocate_xrif()
Worker function to configure and allocate the xrif handles.
std::string m_rawimageDir
The path where files will be saved.
double m_maxCircBuffSize
The maximum size of the circular bufffer in MB.
int doEncode()
Function called when semaphore is raised to do the encode and write.
uint64_t m_currSaveStop
The circular buffer position at which to stop saving.
std::string m_outFilePath
The full path for the latest output file.
size_t m_width
The width of the image.
#define XWCTEST_INDI_NEW_CALLBACK(testclass, propname)
Catch-2 tests for whether a NEW callback properly validates the input property properly.
Definition dm.hpp:28
#define WRITING
SCENARIO("streamWriter INDI Callbacks", "[streamWriter]")
int comp_frames_uint16(size_t start, size_t stop)
streamWriter_data_test(streamWriter_test *sw)
int setup_circbufs(int width, int height, int dataType, int circBuffLength, int writeChunkLength)
streamWriter_test(const std::string &device)
#define XWCTEST_SETUP_INDI_NEW_PROP(propname)