We have migrated our application to release 7.2 and (almost) everything is working fine when deploying the application on any existing database. However, when running the unit tests, it fails on the code that we’ve added and that is executed on the application start:
@Override
public void applicationStarted() {
authentication.begin();
try {
// Do all kinds of database preparation (imports, migrations etc.)
} finally {
authentication.end();
}
}
Note that we do an authentication.begin() to make sure we have a system user session that allows us to do database modifications.
Within the unit test container, we call upon the application start:
@Override
public void before() throws Throwable {
if (!initialized) {
super.before();
// Initialise platform once
AppLifecycle appLifecycle = AppBeans.get(AppLifecycle.class);
appLifecycle.applicationStarted();
initialized = true;
}
setupContext();
}
Up to the migration to 7.2 everything worked fine but somehow, when running the unit tests now, the authentication.begin() does not return a session with the system user (which should be able to do database modifications) but a session for some unknown server user which is unable to do database modifications and thus makes the unit tests fail later on.
Whatever we do to ensure a proper system user session, it keeps failing and remains to use the unknown server user session.
Any ideas where to find a solution? Any help appreciated!
Hi,
The strange “server” session you are observing is because of the logic in the com.haulmont.cuba.core.sys.AppContext#getSecurityContext class and method.
Before the context is marked as “started”, it always returns initial server session that is meant to be used during server startup.
To mark context as started, call this method in the base test class:
AppContext.Internals.startContext();
It will set “started” flag to true, and also call all applicationStarted and AppContextStartedEvent event listeners.
This change in code may lead to other side effects, such as mechanism scheduling tasks activated in tests. Disable it for tests using “cuba.schedulingActive = false” property.
Thanks for your help and indeed, this does improve the situation and the authentication.begin() now results in a proper session which is great.
However, strangely enough the init during the unit test is still different from normal startup and still fails as a result of the system user session not being able to insert any records into the database (ENTITY_OP:CREATE being denied). Whereas normal startup on a clean / newly defined database works fine which does exactly the same operations on the same user session.
Thanks for the hint, this lead me to check the test-spring.xml and from there our UserSessionSource override. I needed to add the session.setJoinedRole() for this to work properly:
@Override
public UserSession getUserSession() {
if (session == null) {
Staff user = dataManager.create(Staff.class);
user.setId(UUID.fromString(USER_ID));
user.setName("admin");
user.setLogin("admin");
user.setPassword(DigestUtils.md5Hex("admin"));
session = new UserSession(UUID.randomUUID(), user, Collections.emptyList(), Locale.forLanguageTag("en"), false);
session.setJoinedRole(new TestFullAccessRole());
}
return session;
}