220 lines
11 KiB
C++
220 lines
11 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "tests/config.h"
|
|
#include "tests/common/helpers.h"
|
|
#include "tests/fixture/authenticationFixture.h"
|
|
#include "tests/fixture/loginMockFixture.h"
|
|
#include "tests/mock/mockLogDevice.h"
|
|
#include "tests/mock/mockResultHelper.h"
|
|
#include "tests/mock/parametersMockHelper.h"
|
|
#include <../private/ubiservices/core/extensions/enumeration.h>
|
|
|
|
namespace US_NS {;
|
|
US_DEFINE_TEST(TestExtendSession);
|
|
|
|
typedef AuthenticationFixture<1> EXTEND_SESSION;
|
|
typedef LoginMockFixture<false> EXTEND_SESSION_MOCK_NOLOGIN;
|
|
|
|
namespace TestSuspendedMode_BF
|
|
{
|
|
#if defined(US_SDK_S2S)
|
|
const char* const EXTEND_SESSION_ENDPOINT = "/applications/sessions";
|
|
#else
|
|
const char* const EXTEND_SESSION_ENDPOINT = "/profiles/sessions";
|
|
#endif
|
|
|
|
#if !defined(US_SDK_S2S)
|
|
AuthenticationNotificationType waitForExtendSessionNotification(Facade& facade, DurationNano waitTime);
|
|
#endif
|
|
AuthenticationNotificationType waitForExtendSessionNotification(ListenerHandler<AuthenticationNotification>& listener, DurationNano waitTime);
|
|
}
|
|
|
|
namespace TestExtendSession_BF
|
|
{
|
|
AuthenticationNotificationType waitForNotification(
|
|
ListenerHandler<AuthenticationNotification>& listener,
|
|
DurationMicro waitNano = DurationMicro(DurationMilli(NS_COMMON::DEFAULT_WAIT_TIME)))
|
|
{
|
|
return TestSuspendedMode_BF::waitForExtendSessionNotification(listener, DurationNano(waitNano));
|
|
}
|
|
}
|
|
|
|
#if !defined(US_DLL)
|
|
|
|
#if !defined(DECLARE_TEST_EXTEND_SESSION_HELPER)
|
|
#define DECLARE_TEST_EXTEND_SESSION_HELPER
|
|
struct TestExtendSessionHelper
|
|
{
|
|
US_FRIEND_TEST(EXTEND_SESSION, US_ExtendSession);
|
|
US_FRIEND_TEST(USTK_NOLOGIN_NOSCHEDULER, USNOT_ExerciseRenewTicket);
|
|
static void reduceSessionDuration(Facade& facade, uint64 expirationTimeMs); // For test purposes ONLY
|
|
};
|
|
#endif // !defined(DECLARE_TEST_EXTEND_SESSION_HELPER)
|
|
|
|
TEST_F(EXTEND_SESSION, US_ExtendSession)
|
|
{
|
|
//#define ENABLING_VERBOSE_LOGGING
|
|
#if defined(ENABLING_VERBOSE_LOGGING)
|
|
LoggingHelper::enableVerbose();
|
|
LoggingHelper::enableMultiLines();
|
|
#endif
|
|
//setupDebugLogging();
|
|
waitForPostLoginCompletion();
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
TestExtendSessionHelper::reduceSessionDuration(getFacade(), ClockSteady::getTimeMilli() + 500); // Setup expiration
|
|
|
|
ASSERT_EQ(AuthenticationNotificationType::SessionInfoChanged, TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(5))));
|
|
|
|
const SessionInfo sessionInfo = getFacade().getAuthenticationClient().getSessionInfo();
|
|
ASSERT_TRUE(sessionInfo.hasValidSession());
|
|
#if defined(US_SDK_S2S)
|
|
EXPECT_FALSE(sessionInfo.getTicket().isEmpty());
|
|
#else
|
|
EXPECT_FALSE(sessionInfo.getNameOnPlatform().isEmpty());
|
|
EXPECT_TRUE(sessionInfo.getProfileId().isValid());
|
|
// Running next line triggers an assert if the PlayerCredential is not set.
|
|
sessionInfo.getPlayerCredentials();
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/// @test Checks that the extend session is retried appropriately
|
|
TEST_F(EXTEND_SESSION_MOCK_NOLOGIN, USNOT_LONG_ExtendSessionRetry)
|
|
{
|
|
{
|
|
const uint8 SESSION_DURATION_SECONDS = 20; // TODO: Review this value to shorten the test duration
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SESSION_DURATION_SECONDS, false);
|
|
const MockAsyncResult failedExtendSession = MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1000);
|
|
|
|
mockFullLogin(&sessionResult);
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, TestSuspendedMode_BF::EXTEND_SESSION_ENDPOINT)
|
|
.Times(3)
|
|
.WillOnce(testing::Return(failedExtendSession))
|
|
.WillOnce(testing::Return(failedExtendSession))
|
|
.WillOnce(testing::Return(getMockedLoginResponseNoUbiAccount())); //works on last attempt.
|
|
}
|
|
|
|
// Performs a login to trigger the extend session
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(GET_CREDENTIALS(), {}, {})));
|
|
|
|
const AuthenticationNotificationType notifCreateSession = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(6)));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notifCreateSession) << "We didn't get the expected notification for createSession.";
|
|
|
|
const AuthenticationNotificationType notif = TestExtendSession_BF::waitForNotification(notificationListener);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notif) << "We didn't get the expected client notification.";
|
|
}
|
|
|
|
/// @test Checks that the extend session is retried and that it sends the according notification when it fails.
|
|
TEST_F(EXTEND_SESSION_MOCK_NOLOGIN, USNOT_LONG_ExtendSessionFailure)
|
|
{
|
|
PrepareLoggingMock([](US_TEST_NS::MockLogDevice& device)
|
|
{
|
|
// Note : Since we return an error, all mandatory fields in SessionInfo are missing and will all raise a log
|
|
// This will happen for each extend session retry
|
|
// so there should be (number of session retries) * (number of mandatory sessionInfo fields) logs
|
|
const uint32 NUMBER_OF_EXTENDSESSION_RETRIES = 3;
|
|
const uint32 NUMBER_OF_MANDATORY_FIELDS_IN_SESSIONINFO = 9;
|
|
US_EXPECT_LOG("Missing mandatory field:", LogLevel::Error,
|
|
Times(NUMBER_OF_EXTENDSESSION_RETRIES * NUMBER_OF_MANDATORY_FIELDS_IN_SESSIONINFO));
|
|
US_EXPECT_LOG("Failed to extend the current session because of invalid JSON:", LogLevel::Error, Times(3));
|
|
});
|
|
{
|
|
const uint8 SESSION_DURATION_SECONDS = 20; // TODO: Review this value to shorten the test duration
|
|
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SESSION_DURATION_SECONDS, false);
|
|
mockFullLogin(&sessionResult);
|
|
|
|
const MockAsyncResult failedExtendSession = MockResultHelper::createRestErrorResult(RestStatusCode::Error404, 1000);
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, TestSuspendedMode_BF::EXTEND_SESSION_ENDPOINT)
|
|
.Times(3)
|
|
.WillRepeatedly(testing::Return(failedExtendSession)); // fails on all attempts
|
|
}
|
|
|
|
// Performs a login to trigger the extend session
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(GET_CREDENTIALS(), {}, {})));
|
|
|
|
const AuthenticationNotificationType notifCreateSession = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(6)));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notifCreateSession) << "We didn't get the expected notification for createSession.";
|
|
|
|
const AuthenticationNotificationType notifExtendSessionFailed = TestExtendSession_BF::waitForNotification(notificationListener);
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionExtensionFailed, notifExtendSessionFailed);
|
|
}
|
|
|
|
/// @test Checks that the extend session is periodic and is achieved several times.
|
|
TEST_F(EXTEND_SESSION_MOCK_NOLOGIN, USNOT_SeveralExtendSession)
|
|
{
|
|
const int ITERATION_COUNT = 3;
|
|
{
|
|
const Duration<uint8> SESSION_DURATION_SECONDS = 5;
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SESSION_DURATION_SECONDS, false);
|
|
mockFullLogin(&sessionResult);
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, TestSuspendedMode_BF::EXTEND_SESSION_ENDPOINT)
|
|
.Times(ITERATION_COUNT)
|
|
.WillRepeatedly(testing::Return(sessionResult));
|
|
}
|
|
|
|
// Performs a login to trigger the extend session
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(GET_CREDENTIALS(), {}, {})));
|
|
|
|
const AuthenticationNotificationType notifCreateSession = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(6)));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notifCreateSession) << "We didn't get the expected notification for createSession.";
|
|
|
|
for (int i = 0; i < ITERATION_COUNT; i++)
|
|
{
|
|
PRINT_PROGRESS(i + 1, ITERATION_COUNT, "Waiting notification %d", i + 1);
|
|
const AuthenticationNotificationType notifExtendSessionFailed = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(6)));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notifExtendSessionFailed) << "We didn't get the expected notification for session extension.";
|
|
}
|
|
}
|
|
|
|
/// @test Checks that there is no session extension when the ExtendSession switch is off.
|
|
/// @note This test is not in the testKillSwitches file mainly because everything
|
|
/// is set in this file to ease making this test. Furthermore, the extendSession
|
|
/// switch does not deactivate communication like other switches, it disables a feature.
|
|
/// Having it in a separate file is therefore not completely absurd...
|
|
TEST_F(EXTEND_SESSION_MOCK_NOLOGIN, USNOT_SwitchedExtendSessionOff)
|
|
{
|
|
const Duration<uint8> SESSION_DURATION_SECONDS = 5;
|
|
{
|
|
const MockAsyncResult sessionResult = getMockedLoginShortSession(SESSION_DURATION_SECONDS, false);
|
|
|
|
auto parametersApplicationResult = getMockedParametersApplication();
|
|
auto parametersSpaceResult = MockResultHelper::createSuccessResult(ParametersSpaceMockHelper().changeFeatureSwitch(FeatureSwitchId::ExtendSession,
|
|
FeatureSwitchState::Disabled).getParameters().renderContent());
|
|
mockFullLogin(&sessionResult, ¶metersApplicationResult, ¶metersSpaceResult);
|
|
|
|
US_EXPECT_CALL_HTTP(getMockHttpClientImpl(), HttpMethod::HTTP_PUT, TestSuspendedMode_BF::EXTEND_SESSION_ENDPOINT).Times(0);
|
|
}
|
|
|
|
// Performs a login to trigger the extend session
|
|
|
|
// Create listener before triggering state change, so we can catch notification
|
|
ListenerHandler<AuthenticationNotification> notificationListener = getFacade().getAuthenticationClient().createNotificationListener();
|
|
|
|
ASSERT_TRUE(AsyncHelper::waitSuccess(getFacade().createSession(GET_CREDENTIALS(), {}, {})));
|
|
|
|
const AuthenticationNotificationType notifCreateSession = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(Duration<>(6)));
|
|
EXPECT_EQ(AuthenticationNotificationType::SessionInfoChanged, notifCreateSession) << "We didn't get the expected notification for createSession.";
|
|
|
|
const AuthenticationNotificationType notifNone = TestExtendSession_BF::waitForNotification(notificationListener, DurationMicro(2*SESSION_DURATION_SECONDS));
|
|
EXPECT_EQ(AuthenticationNotificationType::None, notifNone) << "There should not be an extend session notification.";
|
|
}
|
|
|
|
};
|