Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#11843] Update GetFeedbackSessionLogsAction to use SQL db #12938

Merged
merged 35 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b436465
Create FeedbackSessionLog entity
dishenggg Mar 12, 2024
7a7639c
fix lint
dishenggg Mar 12, 2024
2e8ea28
Create UpdateFeedbackSessionLogsAction
dishenggg Mar 13, 2024
1258fdc
Sort query results from logging service
dishenggg Mar 13, 2024
2cf76c9
Update type of feedbackSessionLogType
dishenggg Mar 13, 2024
d39dd10
Fix naming
dishenggg Mar 13, 2024
f843248
Fix enum in entity
dishenggg Mar 14, 2024
1b1fde5
Update filter to differentiate by session
dishenggg Mar 14, 2024
6faf279
Add Uri Info
dishenggg Mar 14, 2024
11a174e
Add tests
dishenggg Mar 14, 2024
b281ee1
Update test case
dishenggg Mar 14, 2024
2a730bf
Update to getOrderedFeedbackSessionLogs
dishenggg Mar 14, 2024
8010d74
Create skeleton
dishenggg Mar 18, 2024
6078da3
Implement logic and db layer
dishenggg Mar 19, 2024
51c5264
Merge branch 'student-activity-logs' into logs
dishenggg Mar 19, 2024
65db0ae
fix lint
dishenggg Mar 19, 2024
01057cc
Update entity
dishenggg Mar 22, 2024
1007ccd
Fix tests
dishenggg Mar 23, 2024
c7081d2
Update action to use fslDb
dishenggg Mar 24, 2024
7b38b82
Fix tests
dishenggg Mar 25, 2024
5dad6e7
Update DbIT to use databundle
dishenggg Mar 26, 2024
3cf6b15
Fix bugs and optimize action
dishenggg Mar 27, 2024
f36232f
Prevent courseId from being null
dishenggg Mar 27, 2024
3be6183
Update GCP logs to store ids
dishenggg Mar 27, 2024
f015dd3
Fix tests
dishenggg Mar 27, 2024
635ccdb
Update action to use reference
dishenggg Mar 27, 2024
fba4ff2
Add some error handling
dishenggg Mar 28, 2024
9eb2b2e
Fix tests
dishenggg Mar 28, 2024
0da8ac8
Add ids to api output
dishenggg Mar 28, 2024
f21a137
Merge branch 'logs' into logs-getAction
dishenggg Mar 28, 2024
cfe5065
Merge branch 'student-activity-logs' into logs-getAction
dishenggg Mar 28, 2024
9dc40b8
Fix lint
dishenggg Mar 29, 2024
52c6940
Update cron.yaml
dishenggg Mar 29, 2024
4f0bcef
Tidy up code
dishenggg Apr 1, 2024
25c958a
Update comments
dishenggg Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions src/it/java/teammates/it/sqllogic/core/FeedbackSessionLogsLogicIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package teammates.it.sqllogic.core;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import teammates.common.datatransfer.SqlDataBundle;
import teammates.common.datatransfer.logs.FeedbackSessionLogType;
import teammates.common.util.HibernateUtil;
import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.sqllogic.core.FeedbackSessionLogsLogic;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.FeedbackSession;
import teammates.storage.sqlentity.FeedbackSessionLog;
import teammates.storage.sqlentity.Student;

/**
* SUT: {@link FeedbackSessionLogsLogic}.
*/
public class FeedbackSessionLogsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {

private FeedbackSessionLogsLogic fslLogic = FeedbackSessionLogsLogic.inst();

private SqlDataBundle typicalDataBundle;

@Override
@BeforeClass
public void setupClass() {
super.setupClass();
typicalDataBundle = getTypicalSqlDataBundle();
}

@Override
@BeforeMethod
protected void setUp() throws Exception {
super.setUp();
persistDataBundle(typicalDataBundle);
HibernateUtil.flushSession();
HibernateUtil.clearSession();
}

@Test
public void test_createFeedbackSessionLog_success() {
Course course = typicalDataBundle.courses.get("course1");
FeedbackSession fs = typicalDataBundle.feedbackSessions.get("session1InCourse1");
Student student = typicalDataBundle.students.get("student1InCourse1");
Instant timestamp = Instant.now();
FeedbackSessionLog newLog1 = new FeedbackSessionLog(student, fs, FeedbackSessionLogType.ACCESS, timestamp);
FeedbackSessionLog newLog2 = new FeedbackSessionLog(student, fs, FeedbackSessionLogType.SUBMISSION, timestamp);
FeedbackSessionLog newLog3 = new FeedbackSessionLog(student, fs, FeedbackSessionLogType.VIEW_RESULT, timestamp);
List<FeedbackSessionLog> expected = List.of(newLog1, newLog2, newLog3);

fslLogic.createFeedbackSessionLogs(expected);

List<FeedbackSessionLog> actual = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student.getId(),
fs.getId(), timestamp, timestamp.plusSeconds(1));

assertEquals(expected, actual);
}

@Test
public void test_getOrderedFeedbackSessionLogs_success() {
Instant startTime = Instant.parse("2012-01-01T12:00:00Z");
Instant endTime = Instant.parse("2012-01-01T23:59:59Z");
Course course = typicalDataBundle.courses.get("course1");
Student student1 = typicalDataBundle.students.get("student1InCourse1");
FeedbackSession fs1 = typicalDataBundle.feedbackSessions.get("session1InCourse1");

FeedbackSessionLog student1Session1Log1 = typicalDataBundle.feedbackSessionLogs.get("student1Session1Log1");
FeedbackSessionLog student1Session2Log1 = typicalDataBundle.feedbackSessionLogs.get("student1Session2Log1");
FeedbackSessionLog student1Session2Log2 = typicalDataBundle.feedbackSessionLogs.get("student1Session2Log2");
FeedbackSessionLog student2Session1Log1 = typicalDataBundle.feedbackSessionLogs.get("student2Session1Log1");
FeedbackSessionLog student2Session1Log2 = typicalDataBundle.feedbackSessionLogs.get("student2Session1Log2");

______TS("Return logs belonging to a course in time range");
List<FeedbackSessionLog> expectedLogs = List.of(
student1Session1Log1,
student1Session2Log1,
student1Session2Log2,
student2Session1Log1,
student2Session1Log2);

List<FeedbackSessionLog> actualLogs = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null,
startTime, endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a student in a course in time range");
expectedLogs = List.of(
student1Session1Log1,
student1Session2Log1,
student1Session2Log2);

actualLogs = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime,
endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a feedback session in time range");
expectedLogs = List.of(
student1Session1Log1,
student2Session1Log1,
student2Session1Log2);

actualLogs = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a student in a feedback session in time range");
expectedLogs = List.of(student1Session1Log1);

actualLogs = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(),
startTime,
endTime);

assertEquals(expectedLogs, actualLogs);

______TS("No logs in time range, return empty list");
expectedLogs = new ArrayList<>();

actualLogs = fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),
endTime.plusSeconds(7200));

assertEquals(expectedLogs, actualLogs);
}

}
104 changes: 31 additions & 73 deletions src/it/java/teammates/it/storage/sqlapi/FeedbackSessionLogsDbIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,106 +63,64 @@ public void test_createFeedbackSessionLog_success() {

@Test
public void test_getOrderedFeedbackSessionLogs_success() {
Instant startTime = Instant.parse("2011-01-01T00:00:00Z");
Instant endTime = Instant.parse("2011-01-01T01:00:00Z");

Course course1 = typicalDataBundle.courses.get("course1");

FeedbackSession session1 = typicalDataBundle.feedbackSessions.get("session1InCourse1");
FeedbackSession session2 = typicalDataBundle.feedbackSessions.get("session2InTypicalCourse");
FeedbackSession sessionInAnotherCourse = typicalDataBundle.feedbackSessions.get("ongoingSession1InCourse3");

Instant startTime = Instant.parse("2012-01-01T12:00:00Z");
Instant endTime = Instant.parse("2012-01-01T23:59:59Z");
Course course = typicalDataBundle.courses.get("course1");
Student student1 = typicalDataBundle.students.get("student1InCourse1");
Student student2 = typicalDataBundle.students.get("student2InCourse1");

FeedbackSessionLog student1Session1Log1 = new FeedbackSessionLog(student1, session1,
FeedbackSessionLogType.ACCESS, startTime);
FeedbackSessionLog student1Session1Log2 = new FeedbackSessionLog(student1, session1,
FeedbackSessionLogType.SUBMISSION, startTime.plusSeconds(1));
FeedbackSessionLog student1Session1Log3 = new FeedbackSessionLog(student1, session1,
FeedbackSessionLogType.VIEW_RESULT, startTime.plusSeconds(2));
FeedbackSessionLog student1Session2Log1 = new FeedbackSessionLog(student1, session2,
FeedbackSessionLogType.ACCESS, startTime.plusSeconds(3));

FeedbackSessionLog student2Session1Log1 = new FeedbackSessionLog(student2, session1,
FeedbackSessionLogType.ACCESS, startTime.plusSeconds(4));
FeedbackSessionLog student2Session2Log1 = new FeedbackSessionLog(student2, session2,
FeedbackSessionLogType.ACCESS, startTime.plusSeconds(5));

FeedbackSessionLog student1AnotherCourseLog1 = new FeedbackSessionLog(student1, sessionInAnotherCourse,
FeedbackSessionLogType.ACCESS, startTime.plusSeconds(6));

FeedbackSessionLog outOfRangeLog1 = new FeedbackSessionLog(student1, session1, FeedbackSessionLogType.ACCESS,
startTime.minusSeconds(1));
FeedbackSessionLog outOfRangeLog2 = new FeedbackSessionLog(student1, session1, FeedbackSessionLogType.ACCESS,
endTime);

List<FeedbackSessionLog> newLogs = new ArrayList<>();
newLogs.add(student1Session1Log1);
newLogs.add(student1Session1Log2);
newLogs.add(student1Session1Log3);
newLogs.add(student1Session2Log1);

newLogs.add(student2Session1Log1);
newLogs.add(student2Session2Log1);
FeedbackSession fs1 = typicalDataBundle.feedbackSessions.get("session1InCourse1");

newLogs.add(student1AnotherCourseLog1);

newLogs.add(outOfRangeLog1);
newLogs.add(outOfRangeLog2);

for (FeedbackSessionLog log : newLogs) {
fslDb.createFeedbackSessionLog(log);
}
FeedbackSessionLog student1Session1Log1 = typicalDataBundle.feedbackSessionLogs.get("student1Session1Log1");
FeedbackSessionLog student1Session2Log1 = typicalDataBundle.feedbackSessionLogs.get("student1Session2Log1");
FeedbackSessionLog student1Session2Log2 = typicalDataBundle.feedbackSessionLogs.get("student1Session2Log2");
FeedbackSessionLog student2Session1Log1 = typicalDataBundle.feedbackSessionLogs.get("student2Session1Log1");
FeedbackSessionLog student2Session1Log2 = typicalDataBundle.feedbackSessionLogs.get("student2Session1Log2");

______TS("Return logs belonging to a course in time range");
List<FeedbackSessionLog> expectedLogs = new ArrayList<>();
expectedLogs.add(student1Session1Log1);
expectedLogs.add(student1Session1Log2);
expectedLogs.add(student1Session1Log3);
expectedLogs.add(student1Session2Log1);

expectedLogs.add(student2Session1Log1);
expectedLogs.add(student2Session2Log1);

List<FeedbackSessionLog> actualLogs = fslDb.getOrderedFeedbackSessionLogs(course1.getId(), null, null,
List<FeedbackSessionLog> expectedLogs = List.of(
student1Session1Log1,
student1Session2Log1,
student1Session2Log2,
student2Session1Log1,
student2Session1Log2
);

List<FeedbackSessionLog> actualLogs = fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null,
startTime, endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a student in time range");
expectedLogs = new ArrayList<>();
expectedLogs.add(student1Session1Log1);
expectedLogs.add(student1Session1Log2);
expectedLogs.add(student1Session1Log3);
expectedLogs.add(student1Session2Log1);
expectedLogs = List.of(
student1Session1Log1,
student1Session2Log1,
student1Session2Log2);

actualLogs = fslDb.getOrderedFeedbackSessionLogs(course1.getId(), student1.getId(), null, startTime, endTime);
actualLogs = fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime, endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a feedback session in time range");
expectedLogs = new ArrayList<>();
expectedLogs.add(student1Session2Log1);
expectedLogs.add(student2Session2Log1);
expectedLogs = List.of(
student1Session1Log1,
student2Session1Log1,
student2Session1Log2);

actualLogs = fslDb.getOrderedFeedbackSessionLogs(course1.getId(), null, session2.getId(), startTime, endTime);
actualLogs = fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);

assertEquals(expectedLogs, actualLogs);

______TS("Return logs belonging to a student in a feedback session in time range");
expectedLogs = new ArrayList<>();
expectedLogs.add(student2Session2Log1);
expectedLogs = List.of(student1Session1Log1);

actualLogs = fslDb.getOrderedFeedbackSessionLogs(course1.getId(), student2.getId(), session2.getId(), startTime,
actualLogs = fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(), startTime,
endTime);

assertEquals(expectedLogs, actualLogs);

______TS("No logs in time range, return empty list");
expectedLogs = new ArrayList<>();

actualLogs = fslDb.getOrderedFeedbackSessionLogs(course1.getId(), null, null, endTime.plusSeconds(3600),
actualLogs = fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),
endTime.plusSeconds(7200));

assertEquals(expectedLogs, actualLogs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,21 @@ protected String getRequestMethod() {
return GET;
}

@Test
@Test(enabled = false)
@Override
protected void testExecute() {
JsonResult actionOutput;

Course course = typicalBundle.courses.get("course1");
String courseId = course.getId();
FeedbackSession fsa1 = typicalBundle.feedbackSessions.get("session1InCourse1");
FeedbackSession fsa2 = typicalBundle.feedbackSessions.get("session2InTypicalCourse");
String fsa1Name = fsa1.getName();
String fsa2Name = fsa2.getName();
Student student1 = typicalBundle.students.get("student1InCourse1");
Student student2 = typicalBundle.students.get("student2InCourse1");
String student1Email = student1.getEmail();
String student2Email = student2.getEmail();
long endTime = Instant.now().toEpochMilli();
long endTime = Instant.parse("2012-01-02T12:00:00Z").toEpochMilli();
long startTime = endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;
long invalidStartTime = endTime - (Const.LOGS_RETENTION_PERIOD.toDays() + 1) * 24 * 60 * 60 * 1000;

mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa1Name,
FeedbackSessionLogType.ACCESS.getLabel(), startTime);
mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,
FeedbackSessionLogType.ACCESS.getLabel(), startTime + 1000);
mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,
FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 2000);
mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,
FeedbackSessionLogType.ACCESS.getLabel(), startTime + 3000);
mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,
FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 4000);

______TS("Failure case: not enough parameters");
verifyHttpParameterFailure(
Expand Down Expand Up @@ -117,13 +103,6 @@ protected void testExecute() {
};
verifyHttpParameterFailure(paramsInvalid4);

______TS("Failure case: start time is before earliest search time");
verifyHttpParameterFailure(
Const.ParamsNames.COURSE_ID, courseId,
Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(invalidStartTime),
Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)
);

______TS("Success case: should group by feedback session");
String[] paramsSuccessful1 = {
Const.ParamsNames.COURSE_ID, courseId,
Expand Down Expand Up @@ -168,8 +147,56 @@ protected void testExecute() {
Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),
Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),
};
getJsonResult(getAction(paramsSuccessful2));
// No need to check output again here, it will be exactly the same as the previous case
actionOutput = getJsonResult(getAction(paramsSuccessful2));
fslData = (FeedbackSessionLogsData) actionOutput.getOutput();
fsLogs = fslData.getFeedbackSessionLogs();

assertEquals(fsLogs.size(), 6);
assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);

fsLogEntries1 = fsLogs.get(0).getFeedbackSessionLogEntries();
fsLogEntries2 = fsLogs.get(1).getFeedbackSessionLogEntries();

assertEquals(fsLogEntries1.size(), 1);
assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);
assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);

assertEquals(fsLogEntries2.size(), 2);
assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);
assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);
assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);
assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);

______TS("Success case: should accept feedback session");
String[] paramsSuccessful3 = {
Const.ParamsNames.COURSE_ID, courseId,
Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1Name,
Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),
Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),
};
actionOutput = getJsonResult(getAction(paramsSuccessful3));
fslData = (FeedbackSessionLogsData) actionOutput.getOutput();
fsLogs = fslData.getFeedbackSessionLogs();

assertEquals(fsLogs.size(), 6);
assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);
assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);

fsLogEntries1 = fsLogs.get(0).getFeedbackSessionLogEntries();

assertEquals(fsLogEntries1.size(), 3);
assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);
assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);
assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);
assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);
assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);
assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);

// TODO: if we restrict the range from start to end time, it should be tested here as well
}
Expand Down
Loading