1414package io .trino .connector ;
1515
1616import com .google .common .collect .ImmutableMap ;
17- import com .google .inject .Key ;
17+ import com .google .inject .Binder ;
18+ import com .google .inject .Provides ;
19+ import com .google .inject .Singleton ;
20+ import io .airlift .configuration .AbstractConfigurationAwareModule ;
1821import io .trino .Session ;
1922import io .trino .plugin .memory .MemoryPlugin ;
23+ import io .trino .server .ServerConfig ;
2024import io .trino .spi .catalog .CatalogName ;
2125import io .trino .spi .catalog .CatalogProperties ;
2226import io .trino .spi .catalog .CatalogStore ;
27+ import io .trino .spi .catalog .CatalogStoreFactory ;
2328import io .trino .spi .connector .ConnectorName ;
2429import io .trino .testing .DistributedQueryRunner ;
2530import io .trino .testing .H2QueryRunner ;
2631import io .trino .testing .QueryRunner ;
2732import org .junit .jupiter .api .Test ;
2833import org .junit .jupiter .api .parallel .Execution ;
2934
35+ import java .util .ArrayList ;
36+ import java .util .Collection ;
37+ import java .util .List ;
38+ import java .util .Map ;
3039import java .util .Optional ;
3140import java .util .OptionalLong ;
3241
42+ import static io .trino .connector .FileCatalogStore .computeCatalogVersion ;
3343import static io .trino .testing .QueryAssertions .assertQuery ;
3444import static io .trino .testing .QueryAssertions .assertQueryFails ;
3545import static io .trino .testing .QueryAssertions .assertUpdate ;
4050@ Execution (SAME_THREAD )
4151public class TestDynamicCatalogs
4252{
53+ private static final String BROKEN_CATALOG = "broken_catalog" ;
54+ private static final CatalogName BROKEN_CATALOG_NAME = new CatalogName (BROKEN_CATALOG );
55+ private static final ConnectorName MEMORY_CONNECTOR_NAME = new ConnectorName ("memory" );
56+
4357 @ Test
4458 public void testNewHealthyCatalog ()
4559 throws Exception
@@ -51,8 +65,6 @@ public void testNewHealthyCatalog()
5165 .build ();
5266 queryRunner .installPlugin (new MemoryPlugin ());
5367 queryRunner .createCatalog ("healthy_catalog" , "memory" , ImmutableMap .of ("memory.max-data-per-node" , "128MB" ));
54- ConnectorServicesProvider connectorServicesProvider = queryRunner .getCoordinator ().getInstance (new Key <>() {});
55- connectorServicesProvider .loadInitialCatalogs ();
5668 H2QueryRunner h2QueryRunner = new H2QueryRunner ();
5769
5870 assertQuery (queryRunner , session , "SHOW CATALOGS" , h2QueryRunner , "VALUES 'healthy_catalog', 'system'" , false , false );
@@ -72,27 +84,97 @@ public void testNewHealthyCatalog()
7284 public void testNewUnhealthyCatalog ()
7385 throws Exception
7486 {
75- String catalogName = "new_catalog" + randomNameSuffix ();
76- // simulate loading an unhealthy catalog during a startup
7787 Session session = testSession ();
7888 QueryRunner queryRunner = DistributedQueryRunner .builder (session )
89+ .setAdditionalModule (new TestCatalogStoreModule ())
90+ .setCoordinatorProperties (ImmutableMap .of ("catalog.store" , "prepopulated_memory" ))
7991 .setWorkerCount (0 )
8092 .build ();
8193 queryRunner .installPlugin (new MemoryPlugin ());
8294 queryRunner .createCatalog ("healthy_catalog" , "memory" , ImmutableMap .of ("memory.max-data-per-node" , "128MB" ));
8395 H2QueryRunner h2QueryRunner = new H2QueryRunner ();
84- CatalogStore catalogStore = queryRunner .getCoordinator ().getInstance (new Key <>() {});
85- ConnectorServicesProvider connectorServicesProvider = queryRunner .getCoordinator ().getInstance (new Key <>() {});
86- CatalogProperties catalogProperties = catalogStore .createCatalogProperties (new CatalogName (catalogName ), new ConnectorName ("memory" ), ImmutableMap .of ("invalid" , "128MB" ));
87- catalogStore .addOrReplaceCatalog (catalogProperties );
88- connectorServicesProvider .loadInitialCatalogs ();
8996
90- assertQuery (queryRunner , session , "SHOW CATALOGS" , h2QueryRunner , "VALUES 'healthy_catalog', '" + catalogName + "', 'system'" , false , false );
91- assertQueryFails (queryRunner , session , "CREATE TABLE %s.default.test_table (age INT)" .formatted (catalogName ), ".*Catalog '%s' failed to initialize and is disabled.*" .formatted (catalogName ));
92- assertQueryFails (queryRunner , session , "SELECT * FROM %s.default.test_table" .formatted (catalogName ), ".*Catalog '%s' failed to initialize and is disabled.*" .formatted (catalogName ));
93- assertQueryFails (queryRunner , session , "CREATE CATALOG %s USING memory WITH (\" memory.max-data-per-node\" = '128MB')" .formatted (catalogName ), ".*Catalog '%s' already exists.*" .formatted (catalogName ));
97+ assertQuery (queryRunner , session , "SHOW CATALOGS" , h2QueryRunner , "VALUES 'healthy_catalog', '" + BROKEN_CATALOG + "', 'system'" , false , false );
98+ assertQueryFails (queryRunner , session , "CREATE TABLE %s.default.test_table (age INT)" .formatted (BROKEN_CATALOG ), ".*Catalog '%s' failed to initialize and is disabled.*" .formatted (BROKEN_CATALOG ));
99+ assertQueryFails (queryRunner , session , "SELECT * FROM %s.default.test_table" .formatted (BROKEN_CATALOG ), ".*Catalog '%s' failed to initialize and is disabled.*" .formatted (BROKEN_CATALOG ));
100+ assertQueryFails (queryRunner , session , "CREATE CATALOG %s USING memory WITH (\" memory.max-data-per-node\" = '128MB')" .formatted (BROKEN_CATALOG ), ".*Catalog '%s' already exists.*" .formatted (BROKEN_CATALOG ));
94101
95- assertUpdate (queryRunner , session , "DROP CATALOG " + catalogName , OptionalLong .empty (), Optional .empty ());
102+ assertUpdate (queryRunner , session , "DROP CATALOG " + BROKEN_CATALOG , OptionalLong .empty (), Optional .empty ());
96103 assertQuery (queryRunner , session , "SHOW CATALOGS" , h2QueryRunner , "VALUES 'healthy_catalog', 'system'" , false , false );
97104 }
105+
106+ public static class TestCatalogStoreModule
107+ extends AbstractConfigurationAwareModule
108+ {
109+ @ Override
110+ protected void setup (Binder binder )
111+ {
112+ if (buildConfigObject (ServerConfig .class ).isCoordinator ()) {
113+ install (new PrepopulatedInMemoryCatalogStoreModule ());
114+ }
115+ }
116+ }
117+
118+ private static class PrepopulatedInMemoryCatalogStoreModule
119+ extends AbstractConfigurationAwareModule
120+ {
121+ @ Override
122+ protected void setup (Binder binder ) {}
123+
124+ @ Provides
125+ @ Singleton
126+ public PrepopulatedInMemoryCatalogStoreFactory createDbCatalogStoreFactory (CatalogStoreManager catalogStoreManager )
127+ {
128+ PrepopulatedInMemoryCatalogStoreFactory factory = new PrepopulatedInMemoryCatalogStoreFactory ();
129+ catalogStoreManager .addCatalogStoreFactory (factory );
130+ return factory ;
131+ }
132+ }
133+
134+ private static class PrepopulatedInMemoryCatalogStoreFactory
135+ implements CatalogStoreFactory
136+ {
137+ @ Override
138+ public String getName ()
139+ {
140+ return "prepopulated_memory" ;
141+ }
142+
143+ @ Override
144+ public CatalogStore create (Map <String , String > config )
145+ {
146+ return new PrepopulatedInMemoryCatalogStore ();
147+ }
148+ }
149+
150+ private static class PrepopulatedInMemoryCatalogStore
151+ extends InMemoryCatalogStore
152+ {
153+ @ Override
154+ public Collection <StoredCatalog > getCatalogs ()
155+ {
156+ Collection <StoredCatalog > catalogs = super .getCatalogs ();
157+ List <StoredCatalog > catalogsCopy = new ArrayList <>(catalogs );
158+ catalogsCopy .add (new StoredCatalog ()
159+ {
160+ @ Override
161+ public CatalogName name ()
162+ {
163+ return new CatalogName ("broken_catalog" );
164+ }
165+
166+ @ Override
167+ public CatalogProperties loadProperties ()
168+ {
169+ ImmutableMap <String , String > properties = ImmutableMap .of ("non_existing" , "false" );
170+ return new CatalogProperties (
171+ BROKEN_CATALOG_NAME ,
172+ computeCatalogVersion (BROKEN_CATALOG_NAME , MEMORY_CONNECTOR_NAME , properties ),
173+ MEMORY_CONNECTOR_NAME ,
174+ properties );
175+ }
176+ });
177+ return catalogsCopy ;
178+ }
179+ }
98180}
0 commit comments