diff --git a/mondrian/pom.xml b/mondrian/pom.xml
index 55a513f23c..6de70faf7f 100644
--- a/mondrian/pom.xml
+++ b/mondrian/pom.xml
@@ -313,6 +313,48 @@
test
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.cubegrand
+ ${revision}
+ test
+
+
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.cataloggrand
+ ${revision}
+ test
+
+
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.defaultrole
+ ${revision}
+ test
+
+
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.dimensiongrand
+ ${revision}
+ test
+
+
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.hierarchygrand
+ ${revision}
+ test
+
+
+
+ org.eclipse.daanse
+ org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.membergrand
+ ${revision}
+ test
+
+
org.eclipse.daanse
org.eclipse.daanse.rolap.mapping.modifier.common
diff --git a/mondrian/src/test/java/mondrian/test/AccessTest.java b/mondrian/src/test/java/mondrian/test/AccessTest.java
new file mode 100644
index 0000000000..df2934bde4
--- /dev/null
+++ b/mondrian/src/test/java/mondrian/test/AccessTest.java
@@ -0,0 +1,457 @@
+package mondrian.test;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.olap.api.connection.Connection;
+import org.eclipse.daanse.olap.api.connection.ConnectionProps;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.opencube.junit5.ContextSource;
+import org.opencube.junit5.TestUtil;
+import org.opencube.junit5.dataloader.CubeGrandDataLoader;
+import org.opencube.junit5.dataloader.FastFoodmardDataLoader;
+import org.opencube.junit5.propupdator.AppandCubeGrandCatalog;
+import org.opencube.junit5.propupdator.AppandCatalogGrandCatalog;
+import org.opencube.junit5.propupdator.AppandDimensionGrandCatalog;
+import org.opencube.junit5.propupdator.AppandFoodMartCatalog;
+import org.opencube.junit5.propupdator.AppandHierarchyGrandCatalog;
+import org.opencube.junit5.propupdator.AppandMemberGrandCatalog;
+
+import org.opencube.junit5.propupdator.AppandDefaultRoleCatalog;
+
+
+
+public class AccessTest {
+
+ //CubeGrand
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCubeGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCubeGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "42");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCubeGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCubeGrandNoAccessCube2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube2] WHERE ([Measures].[Measure1])",
+ "MDX cube 'Cube2' not found");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCubeGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCubeGrandNoAccessRole2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role2"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube2] WHERE ([Measures].[Measure1])",
+ "Internal error: Role 'role2' not found");
+ }
+
+ //CatalogGrand
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCatalogGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCatalogGrandRoleAll(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("roleAll"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "42");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCatalogGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCatalogGrandRoleAllDimWithCubeGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("roleAllDimWithCubeGrand"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "42");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCatalogGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCatalogGrandRoleAllDimWithoutCubeGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("roleAllDimWithoutCubeGrand"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX cube 'Cube1' not found");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCatalogGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testCatalogGrandRoleNone(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("roleNone"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX cube 'Cube1' not found");
+ }
+
+ //DefaultRole
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDefaultRoleCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDefaultRole(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "84");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDefaultRoleCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDefaultRoleNoRole(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of(), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "84");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDefaultRoleCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDefaultRoleRole2Absent(Context> context) {
+ //catalog have role1. but role2 is absent
+ ConnectionProps props =new ConnectionProps(List.of("role2"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Internal error: Role 'role2' not found");
+ }
+
+ //DimensionGrand
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDimensionGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDimensionGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "84");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDefaultRoleCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDimensionGrandRole2Absent(Context> context) {
+ //catalog have role1. but role2 is absent
+ ConnectionProps props =new ConnectionProps(List.of("role2"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Internal error: Role 'role2' not found");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDimensionGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDimensionGrandDimension1Hierarchy1(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "Axis #1:\n"
+ + "{[Dimension1].[Hierarchy1].[All Hierarchy1s]}\n"
+ + "{[Dimension1].[Hierarchy1].[A]}\n"
+ + "{[Dimension1].[Hierarchy1].[B]}\n"
+ + "{[Dimension1].[Hierarchy1].[C]}\n"
+ + "Row #0: 84\n"
+ + "Row #0: 42\n"
+ + "Row #0: 21\n"
+ + "Row #0: 21\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDimensionGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDimensionGrandDimension1Hierarchy2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy2].[All Hierarchy2s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX object '[Dimension1].[Hierarchy2].[All Hierarchy2s]' not found in cube 'Cube1'");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandDimensionGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testDimensionGrandDimension2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension2].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX object '[Dimension2].[Hierarchy1].[All Hierarchy1s]' not found in cube 'Cube1'");
+ }
+
+ //HierarchyGrand
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandHierarchyGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testHierarchyGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "84");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandHierarchyGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testHierarchyGrandRole2Absent(Context> context) {
+ //catalog have role1. but role2 is absent
+ ConnectionProps props =new ConnectionProps(List.of("role2"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Internal error: Role 'role2' not found");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandHierarchyGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testHierarchyGrandDimension1Hierarchy1(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "Axis #1:\n"
+ + "{[Dimension1].[Hierarchy1].[All Hierarchy1s]}\n"
+ + "{[Dimension1].[Hierarchy1].[A]}\n"
+ + "{[Dimension1].[Hierarchy1].[B]}\n"
+ + "{[Dimension1].[Hierarchy1].[C]}\n"
+ + "Row #0: 84\n"
+ + "Row #0: 42\n"
+ + "Row #0: 21\n"
+ + "Row #0: 21\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandHierarchyGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testHierarchyGrandDimension1Hierarchy2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy2].[All Hierarchy2s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX object '[Dimension1].[Hierarchy2].[All Hierarchy2s]' not found in cube 'Cube1'");
+ }
+
+ //MemberGrand
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandMemberGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testMemberGrand(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "84");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandMemberGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testMemberGrandRole2Absent(Context> context) {
+ //catalog have role1. but role2 is absent
+ ConnectionProps props =new ConnectionProps(List.of("role2"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Internal error: Role 'role2' not found");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandMemberGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testMemberGrandDimension1Hierarchy1(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "Axis #0:\n"
+ + "{[Measures].[Measure1]}\n"
+ + "Axis #1:\n"
+ + "{[Dimension1].[Hierarchy1].[All Hierarchy1s]}\n"
+ + "{[Dimension1].[Hierarchy1].[A]}\n"
+ + "Row #0: 84\n"
+ + "Row #0: 42\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandMemberGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testMemberGrandDimension1Hierarchy2(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("role1"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy2].[All Hierarchy2s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])",
+ "MDX object '[Dimension1].[Hierarchy2].[All Hierarchy2s]' not found in cube 'Cube1'");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandFoodMartCatalog.class, dataloader = FastFoodmardDataLoader.class )
+ void testFoodMartAdministratorSales(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("Administrator"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT {[Measures].Members} ON COLUMNS FROM [SALES]",
+ "Axis #0:\n"
+ + "{}\n"
+ + "Axis #1:\n"
+ + "{[Measures].[Unit Sales]}\n"
+ + "{[Measures].[Store Cost]}\n"
+ + "{[Measures].[Store Sales]}\n"
+ + "{[Measures].[Sales Count]}\n"
+ + "{[Measures].[Customer Count]}\n"
+ + "{[Measures].[Promotion Sales]}\n"
+ + "Row #0: 266,773\n"
+ + "Row #0: 225,627.23\n"
+ + "Row #0: 565,238.13\n"
+ + "Row #0: 86,837\n"
+ + "Row #0: 5,581\n"
+ + "Row #0: 151,211.21\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandFoodMartCatalog.class, dataloader = FastFoodmardDataLoader.class )
+ void testFoodMartAdministratorHR(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("Administrator"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT {[Measures].Members} ON COLUMNS FROM [HR]",
+ "Axis #0:\n"
+ + "{}\n"
+ + "Axis #1:\n"
+ + "{[Measures].[Org Salary]}\n"
+ + "{[Measures].[Count]}\n"
+ + "{[Measures].[Number of Employees]}\n"
+ + "Row #0: $39,431.67\n"
+ + "Row #0: 7,392\n"
+ + "Row #0: 616\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandFoodMartCatalog.class, dataloader = FastFoodmardDataLoader.class )
+ void testFoodMartCaliforniaManageSales(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("California manager"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT {[Measures].Members} ON COLUMNS FROM [SALES]",
+ "Axis #0:\n"
+ + "{}\n"
+ + "Axis #1:\n"
+ + "{[Measures].[Unit Sales]}\n"
+ + "{[Measures].[Store Cost]}\n"
+ + "{[Measures].[Store Sales]}\n"
+ + "{[Measures].[Sales Count]}\n"
+ + "{[Measures].[Customer Count]}\n"
+ + "{[Measures].[Promotion Sales]}\n"
+ + "Row #0: 266,773\n"
+ + "Row #0: 225,627.23\n"
+ + "Row #0: 565,238.13\n"
+ + "Row #0: 86,837\n"
+ + "Row #0: 5,581\n"
+ + "Row #0: 151,211.21\n");
+ }
+
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandFoodMartCatalog.class, dataloader = FastFoodmardDataLoader.class )
+ void testFoodMartNoHRCubeSales(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("No HR Cube"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ Connection connection = context.getConnection(props);
+
+ TestUtil.assertQueryReturns(
+ connection,
+ "SELECT {[Measures].Members} ON COLUMNS FROM [SALES]",
+ "Axis #0:\n"
+ + "{}\n"
+ + "Axis #1:\n"
+ + "{[Measures].[Unit Sales]}\n"
+ + "{[Measures].[Store Cost]}\n"
+ + "{[Measures].[Store Sales]}\n"
+ + "{[Measures].[Sales Count]}\n"
+ + "{[Measures].[Customer Count]}\n"
+ + "{[Measures].[Promotion Sales]}\n"
+ + "Row #0: 266,773\n"
+ + "Row #0: 225,627.23\n"
+ + "Row #0: 565,238.13\n"
+ + "Row #0: 86,837\n"
+ + "Row #0: 5,581\n"
+ + "Row #0: 151,211.21\n");
+ }
+
+ @ParameterizedTest
+ @ContextSource(propertyUpdater = AppandCatalogGrandCatalog.class, dataloader = CubeGrandDataLoader.class )
+ void testFoodMartNoHRCubeHR(Context> context) {
+ ConnectionProps props =new ConnectionProps(List.of("roleAllDimWithoutCubeGrand"), true, Locale.getDefault(), Duration.ofSeconds(-1), Optional.empty(), Optional.empty(), Optional.empty());
+ TestUtil.assertQueryThrows(
+ context,
+ props,
+ "SELECT {[Measures].Members} ON COLUMNS FROM [HR]",
+ "MDX cube 'HR' not found");
+ }
+
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/dataloader/CubeGrandDataLoader.java b/mondrian/src/test/java/org/opencube/junit5/dataloader/CubeGrandDataLoader.java
new file mode 100644
index 0000000000..61db216fa6
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/dataloader/CubeGrandDataLoader.java
@@ -0,0 +1,63 @@
+package org.opencube.junit5.dataloader;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.sql.DataSource;
+
+import org.eclipse.daanse.jdbc.db.dialect.api.Dialect;
+import org.opencube.junit5.Constants;
+
+public class CubeGrandDataLoader implements DataLoader {
+
+ public static List tables = List.of(
+ new DataLoaderUtil.Table(null, "Fact",
+ List.of(),
+ new DataLoaderUtil.Column("KEY", DataLoaderUtil.Type.Varchar30, false), new DataLoaderUtil.Column("VALUE", DataLoaderUtil.Type.Integer, false)));
+
+ @Override
+ public boolean loadData(Entry dataBaseInfo) throws Exception {
+ DataSource dataSource=dataBaseInfo.getKey();
+ Dialect dialect = dataBaseInfo.getValue();
+ try (Connection connection = dataSource.getConnection()) {
+
+
+ List dropTableSQLs = dropTableSQLs(dialect);
+ DataLoaderUtil.executeSql(connection, dropTableSQLs,true);
+
+ List createTablesSqls = createTablesSQLs(dialect);
+ DataLoaderUtil.executeSql(connection, createTablesSqls,true);
+
+ List createIndexesSqls = createIndexSQLs(dialect);
+ DataLoaderUtil.executeSql(connection, createIndexesSqls,true);
+
+ Path dir= Paths.get(Constants.TESTFILES_DIR+"loader/cubegrand/data");
+
+ DataLoaderUtil.importCSV(dataSource, dialect, tables,dir);
+
+ }
+ return true;
+ }
+
+ private List dropTableSQLs(Dialect dialect) throws Exception {
+
+ return tables.stream().map(t -> DataLoaderUtil.dropTableSQL(t, dialect)).toList();
+
+ }
+
+ private List createTablesSQLs(Dialect dialect) throws Exception {
+
+ return tables.stream().map(t -> DataLoaderUtil.createTableSQL(t, dialect)).toList();
+
+ }
+
+ private List createIndexSQLs(Dialect dialect) throws Exception {
+
+ return tables.stream().flatMap(t -> DataLoaderUtil.createIndexSqls(t, dialect).stream()).toList();
+ }
+
+
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCatalogGrandCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCatalogGrandCatalog.java
new file mode 100644
index 0000000000..0f59f06934
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCatalogGrandCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.cataloggrand.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandCatalogGrandCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCubeGrandCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCubeGrandCatalog.java
new file mode 100644
index 0000000000..ac642c002a
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandCubeGrandCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.cubegrand.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandCubeGrandCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDefaultRoleCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDefaultRoleCatalog.java
new file mode 100644
index 0000000000..004947487e
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDefaultRoleCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.defaultrole.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandDefaultRoleCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDimensionGrandCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDimensionGrandCatalog.java
new file mode 100644
index 0000000000..5edb98a25a
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandDimensionGrandCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.dimensiongrand.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandDimensionGrandCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandHierarchyGrandCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandHierarchyGrandCatalog.java
new file mode 100644
index 0000000000..88124b955e
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandHierarchyGrandCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.hierarchygrand.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandHierarchyGrandCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandMemberGrandCatalog.java b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandMemberGrandCatalog.java
new file mode 100644
index 0000000000..48ead5b1f4
--- /dev/null
+++ b/mondrian/src/test/java/org/opencube/junit5/propupdator/AppandMemberGrandCatalog.java
@@ -0,0 +1,12 @@
+package org.opencube.junit5.propupdator;
+
+import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.rolap.mapping.instance.emf.tutorial.access.membergrand.CatalogSupplier;
+import org.opencube.junit5.context.TestContext;
+
+public class AppandMemberGrandCatalog implements TestContextUpdater {
+ @Override
+ public void updateContext(Context> context) {
+ ((TestContext)context).setCatalogMappingSupplier(new CatalogSupplier());
+ }
+}
diff --git a/mondrian/testfiles/loader/cubegrand/data/Fact.csv b/mondrian/testfiles/loader/cubegrand/data/Fact.csv
new file mode 100644
index 0000000000..a73caee4a3
--- /dev/null
+++ b/mondrian/testfiles/loader/cubegrand/data/Fact.csv
@@ -0,0 +1,4 @@
+"KEY","VALUE"
+A,42
+B,21
+C,21