2626import json
2727import tempfile
2828from typing import Any , Mapping , MutableMapping
29+ from unittest .mock import MagicMock
2930
3031import pytest
3132from airbyte_cdk .logger import AirbyteLogger
3233from airbyte_cdk .models import ConfiguredAirbyteCatalog
33- from airbyte_cdk .sources import Source
34+ from airbyte_cdk .sources import AbstractSource , Source
35+ from airbyte_cdk .sources .streams .core import Stream
36+ from airbyte_cdk .sources .streams .http .http import HttpStream
3437
3538
3639class MockSource (Source ):
@@ -51,6 +54,40 @@ def source():
5154 return MockSource ()
5255
5356
57+ @pytest .fixture
58+ def abstract_source (mocker ):
59+ mocker .patch .multiple (HttpStream , __abstractmethods__ = set ())
60+ mocker .patch .multiple (Stream , __abstractmethods__ = set ())
61+
62+ class MockHttpStream (MagicMock , HttpStream ):
63+ url_base = "http://example.com"
64+ path = "/dummy/path"
65+
66+ def __init__ (self , * args , ** kvargs ):
67+ MagicMock .__init__ (self )
68+ HttpStream .__init__ (self , * args , kvargs )
69+ self .read_records = MagicMock ()
70+
71+ class MockStream (MagicMock , Stream ):
72+ page_size = None
73+
74+ def __init__ (self , * args , ** kvargs ):
75+ MagicMock .__init__ (self )
76+ self .read_records = MagicMock ()
77+
78+ streams = [MockHttpStream (), MockStream ()]
79+
80+ class MockAbstractSource (AbstractSource ):
81+ def check_connection (self ):
82+ return True , None
83+
84+ def streams (self , config ):
85+ self .streams_config = config
86+ return streams
87+
88+ return MockAbstractSource ()
89+
90+
5491def test_read_state (source ):
5592 state = {"updated_at" : "yesterday" }
5693
@@ -81,3 +118,60 @@ def test_read_catalog(source):
81118 catalog_file .flush ()
82119 actual = source .read_catalog (catalog_file .name )
83120 assert actual == expected
121+
122+
123+ def test_internal_config (abstract_source ):
124+ configured_catalog = {
125+ "streams" : [
126+ {
127+ "stream" : {"name" : "mock_http_stream" , "json_schema" : {}},
128+ "destination_sync_mode" : "overwrite" ,
129+ "sync_mode" : "full_refresh" ,
130+ },
131+ {
132+ "stream" : {"name" : "mock_stream" , "json_schema" : {}},
133+ "destination_sync_mode" : "overwrite" ,
134+ "sync_mode" : "full_refresh" ,
135+ },
136+ ]
137+ }
138+ catalog = ConfiguredAirbyteCatalog .parse_obj (configured_catalog )
139+ streams = abstract_source .streams (None )
140+ assert len (streams ) == 2
141+ http_stream = streams [0 ]
142+ non_http_stream = streams [1 ]
143+ assert isinstance (http_stream , HttpStream )
144+ assert not isinstance (non_http_stream , HttpStream )
145+ http_stream .read_records .return_value = [{}] * 3
146+ non_http_stream .read_records .return_value = [{}] * 3
147+
148+ # Test with empty config
149+ records = [r for r in abstract_source .read (logger = MagicMock (), config = {}, catalog = catalog , state = {})]
150+ # 3 for http stream and 3 for non http stream
151+ assert len (records ) == 3 + 3
152+ assert http_stream .read_records .called
153+ assert non_http_stream .read_records .called
154+ # Make sure page_size havent been set
155+ assert not http_stream .page_size
156+ assert not non_http_stream .page_size
157+ # Test with records limit set to 1
158+ internal_config = {"some_config" : 100 , "_limit" : 1 }
159+ records = [r for r in abstract_source .read (logger = MagicMock (), config = internal_config , catalog = catalog , state = {})]
160+ # 1 from http stream + 1 from non http stream
161+ assert len (records ) == 1 + 1
162+ assert "_limit" not in abstract_source .streams_config
163+ assert "some_config" in abstract_source .streams_config
164+ # Test with records limit set to number that exceeds expceted records
165+ internal_config = {"some_config" : 100 , "_limit" : 20 }
166+ records = [r for r in abstract_source .read (logger = MagicMock (), config = internal_config , catalog = catalog , state = {})]
167+ assert len (records ) == 3 + 3
168+
169+ # Check if page_size paramter is set to http instance only
170+ internal_config = {"some_config" : 100 , "_page_size" : 2 }
171+ records = [r for r in abstract_source .read (logger = MagicMock (), config = internal_config , catalog = catalog , state = {})]
172+ assert "_page_size" not in abstract_source .streams_config
173+ assert "some_config" in abstract_source .streams_config
174+ assert len (records ) == 3 + 3
175+ assert http_stream .page_size == 2
176+ # Make sure page_size havent been set for non http streams
177+ assert not non_http_stream .page_size
0 commit comments