From f70dc698686ebc1e835cd32cf5c5b25dc25085ba Mon Sep 17 00:00:00 2001
From: tmnaqeesha <tmnaqeesha@users.noreply.github.com>
Date: Sun, 25 May 2025 22:03:28 +0200
Subject: [PATCH] feat: Add performance test

---
 src/tests/RenderingTest.java      | 89 ++++++++++++++++++++++++-------
 src/tests/ReviewItemBookTest.java |  6 +--
 src/tests/Tools.java              | 70 ++++++++++++++++++++----
 3 files changed, 135 insertions(+), 30 deletions(-)

diff --git a/src/tests/RenderingTest.java b/src/tests/RenderingTest.java
index 8eae4bd..3fd028c 100644
--- a/src/tests/RenderingTest.java
+++ b/src/tests/RenderingTest.java
@@ -1,33 +1,86 @@
 package tests;
 
 import opinion.*;
-import teacherTests.Tools;
 
 public class RenderingTest {
 
-    public static void main(String[] args) {
+    private static void runAddMembers() throws Exception {
+        System.out.println("------------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
         ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbMembersAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 0, 0, 0);  // avg per op in nanoseconds
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
 
-        try {
-            int nbMembers = 500;
-            int nbBooks = 2500;
-            int nbFilms = 2500;
-            int nbReviews = 0;
+    private static void runAddBooks() throws Exception {
+        System.out.println("----------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
+        ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbBooksAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, i, 0, 0);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
 
-            int totalOperations = nbMembers + nbBooks + nbFilms + nbReviews;
-            long startTime = System.nanoTime();
-            Tools.populate(sn, nbMembers, nbBooks, nbFilms, nbReviews);
-            long endTime = System.nanoTime();
-            long totalTimeNano = endTime - startTime;
-            double totalTime = totalTimeNano / 1_000_000_000.0;
+    private static void runAddFilms() throws Exception {
+        System.out.println("----------------------------------");
+        Tools.resetCounters();
+        int i = 1000;
+        int max = 10000;
+        ISocialNetwork sn = new SocialNetwork();
+        System.out.println("nbFilmsAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 0, i, 0);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
 
-            System.out.println("\nRENDERING TEST - " + nbMembers + " members, " + nbBooks + " books and " + nbFilms + " films.");
-            System.out.printf("Total number of operations: %d", totalOperations);
-            System.out.printf("\nTotal time taken: %.3f s%n", totalTime);
+    private static void runAddReviews() throws Exception {
+        System.out.println("------------------------------------");
+        int i = 1000;
+        int max = 10000;
+        System.out.println("nbReviewsAdded | totalTime | avgTime");
+        for (int current = i; current <= max; current += i) {
+            ISocialNetwork sn = new SocialNetwork();
+            Tools.resetCounters();
+            long before = System.nanoTime();
+            long avgTimeNano = Tools.populate(sn, i, 10, 10, i);
+            long after = System.nanoTime();
+            double totalTime = (after - before) / 1_000_000.0;
+            double avgTime = avgTimeNano / 1_000_000.0;
+            System.out.printf("%d | %.3fms | %.3fms%n", current, totalTime, avgTime);
+        }
+    }
 
+    public static void main(String[] args) {
+        try {
+            runAddMembers();
+            runAddBooks();
+            runAddFilms();
+            runAddReviews();
         } catch (Exception e) {
-            System.out.println("Error occured in performance test : " + e.getMessage());
+            System.out.println("Error : " + e.getMessage());
             e.printStackTrace();
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/tests/ReviewItemBookTest.java b/src/tests/ReviewItemBookTest.java
index 327b417..4eb6b48 100644
--- a/src/tests/ReviewItemBookTest.java
+++ b/src/tests/ReviewItemBookTest.java
@@ -125,15 +125,15 @@ public class ReviewItemBookTest {
 
         // Nominal cases
 
-        // Test 3.1 : First review for "El Hobbit", expects average mark of 4.0
+        // Test 3.8 : First review for "El Hobbit", expects average mark of 4.0
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 4.0f, "So good", 4.0f, "3.8");
 
-        // Test 3.2 : Second review from another user, expects average of (4.0 + 5.0) ÷ 2 = 4.5
+        // Test 3.9 : Second review from another user, expects average of (4.0 + 5.0) ÷ 2 = 4.5
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Maryam", "1234pass", "El Hobbit", 5.0f, "Perfect", 4.5f, "3.9");
 
-        // Test 3.3: Update Neva's review to 3.0, expects average of (3.0 + 5.0) ÷ 2 = 4.0
+        // Test 3.10: Update Neva's review to 3.0, expects average of (3.0 + 5.0) ÷ 2 = 4.0
         nbTests++;
         nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 3.0f, "Good but too long", 4.0f, "3.11");
 
diff --git a/src/tests/Tools.java b/src/tests/Tools.java
index 4805919..4f34ef3 100644
--- a/src/tests/Tools.java
+++ b/src/tests/Tools.java
@@ -1,4 +1,4 @@
-package teacherTests;
+package tests;
 
 import opinion.ISocialNetwork;
 import exceptions.*;
@@ -18,9 +18,9 @@ public class Tools {
      * They represent the number of members/books/films already generated via Tools
      * but depending on other actions made on the ISocialNetwork, they may differ from its actual 'numbers' of members/books/films
      */
-    private static int nextMember=1; // next value for members (cf logins/passwords)
-    private static int nextBook=1;   // next value for books (cf title)
-    private static int nextFilm=1;   // next value for films (cf title)
+    private static int nextMember = 1; // next value for members (cf logins/passwords)
+    private static int nextBook = 1;   // next value for books (cf title)
+    private static int nextFilm = 1;   // next value for films (cf title)
 
     /*
      * These constants are String or prefix-String to be used when generating new members/books/films/reviews
@@ -40,9 +40,14 @@ public class Tools {
 
     private static final String COMMENT = "comment";
 
-
-
-
+    /**
+     * Resets the counter for number of members, books and films.
+     */
+    public static void resetCounters() {
+        nextMember = 1;
+        nextBook = 1;
+        nextFilm = 1;
+    }
 
     /**
      * Adds members, books, films and reviews to the ISocialNetwork, according to the following process :<br>
@@ -136,7 +141,10 @@ public class Tools {
 
 
             for (int i = 0; i<nbBookReviews;i++) {// add a book review
-                itemNum = 1 + randomGenerator.nextInt(nextBook-2); // choose randomly a book to review - some tricks here, dealing with boundaries
+//                itemNum = 1 + randomGenerator.nextInt(nextBook-2); // choose randomly a book to review - some tricks here, dealing with boundaries
+                int max = Math.max(1, nextBook - 2);  // ensure bound is at least 1
+                itemNum = 1 + randomGenerator.nextInt(max);
+
                 before = System.nanoTime();
                 sn.reviewItemBook(LOGIN+currentMemberNum, PASSWORD+currentMemberNum, TITLE+itemNum, 5*randomGenerator.nextFloat(), COMMENT);
                 currentMemberNum = (currentMemberNum>1)  ? currentMemberNum-1 : nextMember-1; // decrementing modulo nextMember
@@ -146,7 +154,10 @@ public class Tools {
             }
 
             for (int i = 0; i<nbFilmReviews;i++) {// add a film review
-                itemNum = 1 + randomGenerator.nextInt(nextFilm-2); // choose randomly a film to review - some tricks here, dealing with boundaries
+//                itemNum = 1 + randomGenerator.nextInt(nextFilm-2); // choose randomly a film to review - some tricks here, dealing with boundaries
+                int max = Math.max(1, nextFilm - 2);
+                itemNum = 1 + randomGenerator.nextInt(max);
+
                 before = System.nanoTime();
                 sn.reviewItemFilm(LOGIN+currentMemberNum, PASSWORD+currentMemberNum, TITLE+itemNum, 5*randomGenerator.nextFloat(), COMMENT);
                 currentMemberNum = (currentMemberNum>1)  ? currentMemberNum-1 : nextMember-1; // decrementing modulo nextMember
@@ -159,4 +170,45 @@ public class Tools {
         return elapsedTime/totalNbOfOperations;
 
     }
+
+    /**
+     * Verifies if the SocialNetwork prototype can handle 500 members and 5000 items within 2 seconds.
+     * Verifies if disk space has ≤ 10 GB + 1 GB per 1000 users/items
+     */
+    public static void testPerformancePrototype() {
+        ISocialNetwork sn = new opinion.SocialNetwork();
+        resetCounters();
+
+        int nbMembers = 500;
+        int nbBooks = 2500;
+        int nbFilms = 2500;
+        int nbReviews = 1000;
+
+        try {
+            long before = System.nanoTime();
+            long avgNano = populate(sn, nbMembers, nbBooks, nbFilms, nbReviews);
+            long after = System.nanoTime();
+
+            double totalMillis = (after - before) / 1_000_000.0;
+            double avgMillis = avgNano / 1_000_000.0;
+
+            int totalStorage = (int) Math.ceil(nbMembers / 1000.0 + (nbBooks + nbFilms) / 1000.0) + 10; // Disk space: base 10GB + 1GB per 1000 members and 1000 items
+
+            System.out.println("Prototype Performance Test");
+            System.out.printf("Total members: %d\n", nbMembers);
+            System.out.printf("Total items: %d (%d books & %d films)\n", nbBooks + nbFilms, nbBooks, nbFilms);
+            System.out.printf("Total reviews: %d\n", nbReviews);
+            System.out.printf("Total execution time: %.3f ms\n", totalMillis);
+            System.out.printf("Average operation time: %.6f ms\n", avgMillis);
+            System.out.printf("Meets time requirement: %s\n", totalMillis <= 2000 ? "YES" : "NO");
+            System.out.printf("Estimated disk space required: %d GB\n", totalStorage);
+        } catch (Exception e) {
+            System.out.println("Error : " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        Tools.testPerformancePrototype();
+    }
 }
\ No newline at end of file
-- 
GitLab