Check firebird.log [no messages found for interval when this test was running]
Jump to: output_first_mismatch    outcomes_full_history    elapsed_time_chart
Show cross-report outcomes.

Annotation type Annotation details
2 @message
firebird.driver.types.DatabaseError: feature is not supported

LOG DETAILS:

2025-04-18 15:27:55.190
2025-04-18 15:27:55.201 act = <firebird.qa.plugin.Action object at [hex]>
2025-04-18 15:27:55.213 tmp_blob_file = PosixPath('/var/tmp/qa_2024/test_11839/tmp_small_blob.dat')
2025-04-18 15:27:55.227 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-04-18 15:27:55.241
2025-04-18 15:27:55.256 @pytest.mark.version('>=5.0.3')
2025-04-18 15:27:55.269 def test_1(act: Action, tmp_blob_file: Path, capsys):
2025-04-18 15:27:55.283 with act.db.connect() as con:
2025-04-18 15:27:55.293 cur1 = con.cursor()
2025-04-18 15:27:55.307 cur1.execute("select rdb$get_context('SYSTEM', 'CLIENT_VERSION') as client_version from rdb$database")
2025-04-18 15:27:55.318 hdr=cur1.description
2025-04-18 15:27:55.326 for r in cur1:
2025-04-18 15:27:55.342 for i in range(0,len(hdr)):
2025-04-18 15:27:55.354 print( hdr[i][0],':', r[i] )
2025-04-18 15:27:55.368 print(f'{con.info.version=}, {con.info.get_info(DbInfoCode.PROTOCOL_VERSION)=}')
2025-04-18 15:27:55.378
2025-04-18 15:27:55.387 failed_count = 0
2025-04-18 15:27:55.395 for b_range_mnemona, b_len_checked_range in CHECKED_LEN_RANGES.items():
2025-04-18 15:27:55.402 print(f'Preparing data, {b_range_mnemona=}, {b_len_checked_range=}')
2025-04-18 15:27:55.409 for b_gen_size in range(b_len_checked_range[0], b_len_checked_range[1]+1):
2025-04-18 15:27:55.417 print(f'\nGenerate file with data to be stored further in blob field, {b_len_checked_range=}, {b_gen_size=}')
2025-04-18 15:27:55.424 with open(tmp_blob_file, 'wb') as f_binary_data:
2025-04-18 15:27:55.432 f_binary_data.write( bytearray( ''.join(random.choices(string.ascii_letters + string.digits, k = b_gen_size)).encode('ascii') ) )
2025-04-18 15:27:55.439
2025-04-18 15:27:55.453 with open(tmp_blob_file, 'rb') as f_binary_data:
2025-04-18 15:27:55.470 cur1.execute("delete from bdata")
2025-04-18 15:27:55.486 cur1.execute("insert into bdata(blob_fld) values (?)", (f_binary_data,))
2025-04-18 15:27:55.501 con.commit()
2025-04-18 15:27:55.510
2025-04-18 15:27:55.517 cur1.stream_blobs.append('BLOB_FLD')
2025-04-18 15:27:55.525 cur1.execute('select blob_fld from bdata')
2025-04-18 15:27:55.532 blob_reader_1 = cur1.fetchone()[0]
2025-04-18 15:27:55.544
2025-04-18 15:27:55.552 pos_beg, pos_end = b_len_checked_range[:2]
2025-04-18 15:27:55.560 b_read_cnt = 0
2025-04-18 15:27:55.566 for i_pos in range(pos_beg, pos_end+1):
2025-04-18 15:27:55.572 print(f'\n{i_pos=}', ' - *NOTE* WORK BEYOND EOF:' if i_pos > b_gen_size else '')
2025-04-18 15:27:55.579 for whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END):
2025-04-18 15:27:55.587 print(f'\n  Start loop for whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END): {f_binary_data.tell()=}, {blob_reader_1.tell()=}')
2025-04-18 15:27:55.593 if whence == os.SEEK_CUR:
2025-04-18 15:27:55.601 f_binary_data.seek( -min(b_gen_size, (i_pos + b_read_cnt)), os.SEEK_CUR)
2025-04-18 15:27:55.608 blob_reader_1.seek( -min(b_gen_size, (i_pos + b_read_cnt)), os.SEEK_CUR)
2025-04-18 15:27:55.624 print(f'    whence == os.SEEK_CUR --> move back for {-min(b_gen_size, (i_pos + b_read_cnt))=}. Result: {f_binary_data.tell()=}, {blob_reader_1.tell()=}')
2025-04-18 15:27:55.637 elif whence == os.SEEK_END:
2025-04-18 15:27:55.649 b_read_pos = -(pos_end+1 - i_pos)
2025-04-18 15:27:55.663 print(f'    whence == os.SEEK_END: {b_read_pos=}')
2025-04-18 15:27:55.673 if -b_read_pos > b_gen_size:
2025-04-18 15:27:55.691 print(f'    Can not use negative {b_read_pos=} for {whence=} and {b_gen_size=}')
2025-04-18 15:27:55.702 continue
2025-04-18 15:27:55.711 else:
2025-04-18 15:27:55.719 b_read_pos = i_pos
2025-04-18 15:27:55.727 print(f'    whence == os.SEEK_SET: {b_read_pos=}')
2025-04-18 15:27:55.734
2025-04-18 15:27:55.741 print(f'    FILE: f_binary_data.seek({b_read_pos}, {whence=})')
2025-04-18 15:27:55.748 f_binary_data.seek(b_read_pos, whence)
2025-04-18 15:27:55.755 b_read_cnt = pos_end+1 - i_pos
2025-04-18 15:27:55.763 print(f'    FILE: {f_binary_data.tell()=}, attempt to read {b_read_cnt=} bytes starting from {i_pos=} using {whence=}')
2025-04-18 15:27:55.777 b_data_in_file = f_binary_data.read(b_read_cnt)
2025-04-18 15:27:55.792 print(f'    FILE: completed read {b_read_cnt=} bytes starting from {i_pos=} using {whence=}. Result: {f_binary_data.tell()=}, {len(b_data_in_file)=}')
2025-04-18 15:27:55.804
2025-04-18 15:27:55.813 # Now do the same against DB (stream blob):
2025-04-18 15:27:55.821 print(f'    BLOB: blob_reader_1.seek({b_read_pos}, {whence=})')
2025-04-18 15:27:55.828 >                               blob_reader_1.seek(b_read_pos, whence)
2025-04-18 15:27:55.835
2025-04-18 15:27:55.849 tests/functional/blob/test_small_blob_caching.py:162:
2025-04-18 15:27:55.859 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-04-18 15:27:55.868
2025-04-18 15:27:55.875 self = BlobReader[size=0], offset = 0, whence = 0
2025-04-18 15:27:55.883
2025-04-18 15:27:55.892 def seek(self, offset: int, whence: int=os.SEEK_SET) -> None:
2025-04-18 15:27:55.901 """Set the file’s current position, like stdio‘s `fseek()`.
2025-04-18 15:27:55.910
2025-04-18 15:27:55.919 See:
2025-04-18 15:27:55.926 :meth:`io.IOBase.seek()` for details.
2025-04-18 15:27:55.938
2025-04-18 15:27:55.953 Arguments:
2025-04-18 15:27:55.963 offset: Offset from specified position.
2025-04-18 15:27:55.971 whence: Context for offset. Accepted values: os.SEEK_SET, os.SEEK_CUR or os.SEEK_END
2025-04-18 15:27:55.978
2025-04-18 15:27:55.987 Warning:
2025-04-18 15:27:55.996 If BLOB was NOT CREATED as `stream` BLOB, this method raises `DatabaseError`
2025-04-18 15:27:56.009 exception. This constraint is set by Firebird.
2025-04-18 15:27:56.021 """
2025-04-18 15:27:56.030 assert self._blob is not None
2025-04-18 15:27:56.040 >       self.__pos = self._blob.seek(whence, offset)
2025-04-18 15:27:56.053
2025-04-18 15:27:56.064 ../lib/python3.11/site-packages/firebird/driver/core.py:3066:
2025-04-18 15:27:56.071 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-04-18 15:27:56.077
2025-04-18 15:27:56.088 self = <firebird.driver.interfaces.iBlob object at [hex]>, mode = 0
2025-04-18 15:27:56.100 offset = 0
2025-04-18 15:27:56.114
2025-04-18 15:27:56.129 def seek(self, mode: int, offset: int) -> int:
2025-04-18 15:27:56.141 "Replaces isc_seek_blob()"
2025-04-18 15:27:56.151 result = self.vtable.seek(self, self.status, mode, offset)
2025-04-18 15:27:56.159 >       self._check()
2025-04-18 15:27:56.165
2025-04-18 15:27:56.173 ../lib/python3.11/site-packages/firebird/driver/interfaces.py:383:
2025-04-18 15:27:56.181 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-04-18 15:27:56.189
2025-04-18 15:27:56.202 self = <firebird.driver.interfaces.iBlob object at [hex]>
2025-04-18 15:27:56.217
2025-04-18 15:27:56.229 def _check(self) -> None:
2025-04-18 15:27:56.242 state = self.status.get_state()
2025-04-18 15:27:56.253 if StateFlag.ERRORS in state:
2025-04-18 15:27:56.262 >           raise self.__report(DatabaseError, self.status.get_errors())
2025-04-18 15:27:56.271 E           firebird.driver.types.DatabaseError: feature is not supported
2025-04-18 15:27:56.279
2025-04-18 15:27:56.292 ../lib/python3.11/site-packages/firebird/driver/interfaces.py:113: DatabaseError
2025-04-18 15:27:56.301 ---------------------------- Captured stdout setup -----------------------------
2025-04-18 15:27:56.317 Creating db: localhost:/var/tmp/qa_2024/test_11839/test.fdb [page_size=None, sql_dialect=None, charset='NONE', user=SYSDBA, password=masterkey]
2025-04-18 15:27:56.325 ----------------------------- Captured stdout call -----------------------------
2025-04-18 15:27:56.333 CLIENT_VERSION : LI-V5.0.3.1635 Firebird 5.0 HQbird
2025-04-18 15:27:56.341 con.info.version='5.0.3.1635', con.info.get_info(DbInfoCode.PROTOCOL_VERSION)=19
2025-04-18 15:27:56.348 Preparing data, b_range_mnemona='about_00k', b_len_checked_range=(0, 5)
2025-04-18 15:27:56.355
2025-04-18 15:27:56.362 Generate file with data to be stored further in blob field, b_len_checked_range=(0, 5), b_gen_size=0
2025-04-18 15:27:56.375
2025-04-18 15:27:56.386 i_pos=0
2025-04-18 15:27:56.398
2025-04-18 15:27:56.409 Start loop for whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END): f_binary_data.tell()=0, blob_reader_1.tell()=0
2025-04-18 15:27:56.423 whence == os.SEEK_SET: b_read_pos=0
2025-04-18 15:27:56.437 FILE: f_binary_data.seek(0, whence=0)
2025-04-18 15:27:56.446 FILE: f_binary_data.tell()=0, attempt to read b_read_cnt=6 bytes starting from i_pos=0 using whence=0
2025-04-18 15:27:56.454 FILE: completed read b_read_cnt=6 bytes starting from i_pos=0 using whence=0. Result: f_binary_data.tell()=0, len(b_data_in_file)=0
2025-04-18 15:27:56.467 BLOB: blob_reader_1.seek(0, whence=0)
3 #text
act = <firebird.qa.plugin.Action pytest object at [hex]>
tmp_blob_file = PosixPath('/var/tmp/qa_2024/test_11839/tmp_small_blob.dat')
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>

    @pytest.mark.version('>=5.0.3')
    def test_1(act: Action, tmp_blob_file: Path, capsys):
        with act.db.connect() as con:
            cur1 = con.cursor()
            cur1.execute("select rdb$get_context('SYSTEM', 'CLIENT_VERSION') as client_version from rdb$database")
            hdr=cur1.description
            for r in cur1:
                for i in range(0,len(hdr)):
                    print( hdr[i][0],':', r[i] )
            print(f'{con.info.version=}, {con.info.get_info(DbInfoCode.PROTOCOL_VERSION)=}')
    
            failed_count = 0
            for b_range_mnemona, b_len_checked_range in CHECKED_LEN_RANGES.items():
                print(f'Preparing data, {b_range_mnemona=}, {b_len_checked_range=}')
                for b_gen_size in range(b_len_checked_range[0], b_len_checked_range[1]+1):
                    print(f'\nGenerate file with data to be stored further in blob field, {b_len_checked_range=}, {b_gen_size=}')
                    with open(tmp_blob_file, 'wb') as f_binary_data:
                        f_binary_data.write( bytearray( ''.join(random.choices(string.ascii_letters + string.digits, k = b_gen_size)).encode('ascii') ) )
    
                    with open(tmp_blob_file, 'rb') as f_binary_data:
                        cur1.execute("delete from bdata")
                        cur1.execute("insert into bdata(blob_fld) values (?)", (f_binary_data,))
                        con.commit()
    
                        cur1.stream_blobs.append('BLOB_FLD')
                        cur1.execute('select blob_fld from bdata')
                        blob_reader_1 = cur1.fetchone()[0]
    
                        pos_beg, pos_end = b_len_checked_range[:2]
                        b_read_cnt = 0
                        for i_pos in range(pos_beg, pos_end+1):
                            print(f'\n{i_pos=}', ' - *NOTE* WORK BEYOND EOF:' if i_pos > b_gen_size else '')
                            for whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END):
                                print(f'\n  Start loop for whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END): {f_binary_data.tell()=}, {blob_reader_1.tell()=}')
                                if whence == os.SEEK_CUR:
                                    f_binary_data.seek( -min(b_gen_size, (i_pos + b_read_cnt)), os.SEEK_CUR)
                                    blob_reader_1.seek( -min(b_gen_size, (i_pos + b_read_cnt)), os.SEEK_CUR)
                                    print(f'    whence == os.SEEK_CUR --> move back for {-min(b_gen_size, (i_pos + b_read_cnt))=}. Result: {f_binary_data.tell()=}, {blob_reader_1.tell()=}')
                                elif whence == os.SEEK_END:
                                    b_read_pos = -(pos_end+1 - i_pos)
                                    print(f'    whence == os.SEEK_END: {b_read_pos=}')
                                    if -b_read_pos > b_gen_size:
                                        print(f'    Can not use negative {b_read_pos=} for {whence=} and {b_gen_size=}')
                                        continue
                                else:
                                    b_read_pos = i_pos
                                    print(f'    whence == os.SEEK_SET: {b_read_pos=}')
    
                                print(f'    FILE: f_binary_data.seek({b_read_pos}, {whence=})')
                                f_binary_data.seek(b_read_pos, whence)
                                b_read_cnt = pos_end+1 - i_pos
                                print(f'    FILE: {f_binary_data.tell()=}, attempt to read {b_read_cnt=} bytes starting from {i_pos=} using {whence=}')
                                b_data_in_file = f_binary_data.read(b_read_cnt)
                                print(f'    FILE: completed read {b_read_cnt=} bytes starting from {i_pos=} using {whence=}. Result: {f_binary_data.tell()=}, {len(b_data_in_file)=}')
    
                                # Now do the same against DB (stream blob):
                                print(f'    BLOB: blob_reader_1.seek({b_read_pos}, {whence=})')
>                               blob_reader_1.seek(b_read_pos, whence)

tests/functional/blob/test_small_blob_caching.py:162: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = BlobReader[size=0], offset = 0, whence = 0

    def seek(self, offset: int, whence: int=os.SEEK_SET) -> None:
        """Set the file’s current position, like stdio‘s `fseek()`.
    
        See:
            :meth:`io.IOBase.seek()` for details.
    
        Arguments:
            offset: Offset from specified position.
            whence: Context for offset. Accepted values: os.SEEK_SET, os.SEEK_CUR or os.SEEK_END
    
        Warning:
           If BLOB was NOT CREATED as `stream` BLOB, this method raises `DatabaseError`
           exception. This constraint is set by Firebird.
        """
        assert self._blob is not None
>       self.__pos = self._blob.seek(whence, offset)

../lib/python3.11/site-packages/firebird/driver/core.py:3066: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firebird.driver.interfaces.iBlob pytest object at [hex]>, mode = 0
offset = 0

    def seek(self, mode: int, offset: int) -> int:
        "Replaces isc_seek_blob()"
        result = self.vtable.seek(self, self.status, mode, offset)
>       self._check()

../lib/python3.11/site-packages/firebird/driver/interfaces.py:383: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firebird.driver.interfaces.iBlob pytest object at [hex]>

    def _check(self) -> None:
        state = self.status.get_state()
        if StateFlag.ERRORS in state:
>           raise self.__report(DatabaseError, self.status.get_errors())
E           firebird.driver.types.DatabaseError: feature is not supported

../lib/python3.11/site-packages/firebird/driver/interfaces.py:113: DatabaseError
Full history of outcomes and elapsed time, ms:
NN SNAP_INFO CS_outcome SS_outcome CS_run_time SS_run_time CS_run_beg CS_run_end SS_run_beg SS_run_end
1 5.0.3.1674 2025.06.27 3ee5c P P 1269 878 2025.07.03 11:00:46.446 2025.07.03 11:00:47.715 2025.07.03 09:39:16.780 2025.07.03 09:39:17.658
2 5.0.3.1657 2025.06.19 4bd4c P P 1284 994 2025.06.27 12:24:36.620 2025.06.27 12:24:37.904 2025.06.27 11:04:28.126 2025.06.27 11:04:29.120
3 5.0.3.1657 2025.06.11 dae6f P P 1260 867 2025.06.17 07:29:47.524 2025.06.17 07:29:48.784 2025.06.17 06:08:24.564 2025.06.17 06:08:25.431
4 5.0.3.1657 2025.06.10 dbc92 P P 1344 1251 2025.06.11 12:20:24.986 2025.06.11 12:20:26.330 2025.06.11 10:50:35.760 2025.06.11 10:50:37.011
5 5.0.3.1656 2025.05.20 c4b11 P P 1434 982 2025.06.10 12:14:17.108 2025.06.10 12:14:18.542 2025.06.10 10:48:44.478 2025.06.10 10:48:45.460
6 5.0.3.1652 2025.05.13 f51c6 P P 1579 1172 2025.05.20 05:18:54.453 2025.05.20 05:18:56.032 2025.05.20 03:41:23.033 2025.05.20 03:41:24.205
7 5.0.3.1651 2025.04.30 141ef P P 1609 1367 2025.05.13 12:16:58.367 2025.05.13 12:16:59.976 2025.05.13 10:38:20.845 2025.05.13 10:38:22.212
8 5.0.3.1650 2025.04.28 4cbff P P 1568 1176 2025.05.01 11:50:44.532 2025.05.01 11:50:46.100 2025.05.01 10:13:04.519 2025.05.01 10:13:05.695
9 5.0.3.1649 2025.04.21 5b2d0 P P 1558 1186 2025.04.28 05:48:28.981 2025.04.28 05:48:30.539 2025.04.28 04:12:42.402 2025.04.28 04:12:43.588
10 5.0.3.1648 2025.04.18 2f4c5 P P 1672 1070 2025.04.20 05:40:11.706 2025.04.20 05:40:13.378 2025.04.20 04:06:59.448 2025.04.20 04:07:00.518
11 5.0.3.1635 2025.03.31 22ec6 F F 1273 770 2025.04.18 12:03:24.995 2025.04.18 12:03:26.268 2025.04.18 10:26:16.271 2025.04.18 10:26:17.041

Elapsed time, ms. Chart for last 11 runs:

Last commits information (all timestamps in UTC):