diff options
| author | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2025-02-13 18:00:17 +1100 |
|---|---|---|
| committer | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2025-02-13 18:00:17 +1100 |
| commit | 98cef5e9a772602d42acfcf233838c760424db9a (patch) | |
| tree | 5277fa1d7cc0a69a0f166fcbf10fd320f345f049 /comp2511/blackout/tests | |
initial commit
Diffstat (limited to 'comp2511/blackout/tests')
| -rw-r--r-- | comp2511/blackout/tests/Task1Tests.java | 81 | ||||
| -rw-r--r-- | comp2511/blackout/tests/Task2Tests.java | 206 | ||||
| -rw-r--r-- | comp2511/blackout/tests/TestHelpers.java | 14 |
3 files changed, 301 insertions, 0 deletions
diff --git a/comp2511/blackout/tests/Task1Tests.java b/comp2511/blackout/tests/Task1Tests.java new file mode 100644 index 0000000..f5e2a55 --- /dev/null +++ b/comp2511/blackout/tests/Task1Tests.java @@ -0,0 +1,81 @@ +package blackout; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import unsw.blackout.BlackoutController; +import unsw.response.models.EntityInfoResponse; +import unsw.utils.Angle; + +import java.util.Arrays; + +import static blackout.TestHelpers.assertListAreEqualIgnoringOrder; + +@TestInstance(value = Lifecycle.PER_CLASS) +public class Task1Tests { + @Test + public void testCreateDeviceList() { + BlackoutController controller = new BlackoutController(); + + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + controller.createDevice("DeviceB", "LaptopDevice", Angle.fromDegrees(310)); + assertListAreEqualIgnoringOrder(Arrays.asList("DeviceA", "DeviceB"), controller.listDeviceIds()); + } + + @Test + public void testCreateSatelliteList() { + BlackoutController controller = new BlackoutController(); + + controller.createSatellite("S1", "StandardSatellite", 0, Angle.fromDegrees(310)); + controller.createSatellite("S2", "StandardSatellite", 0, Angle.fromDegrees(310)); + assertListAreEqualIgnoringOrder(Arrays.asList("S1", "S2"), controller.listSatelliteIds()); + } + + @Test + public void testRemoveDeviceList() { + BlackoutController controller = new BlackoutController(); + + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + controller.createDevice("DeviceB", "LaptopDevice", Angle.fromDegrees(310)); + assertListAreEqualIgnoringOrder(Arrays.asList("DeviceA", "DeviceB"), controller.listDeviceIds()); + + controller.removeDevice("DeviceB"); + assertListAreEqualIgnoringOrder(Arrays.asList("DeviceA"), controller.listDeviceIds()); + } + + @Test + public void testRemoveSatelliteList() { + BlackoutController controller = new BlackoutController(); + + controller.createSatellite("S1", "StandardSatellite", 0, Angle.fromDegrees(310)); + controller.createSatellite("S2", "StandardSatellite", 0, Angle.fromDegrees(310)); + assertListAreEqualIgnoringOrder(Arrays.asList("S1", "S2"), controller.listSatelliteIds()); + + controller.removeSatellite("S2"); + assertListAreEqualIgnoringOrder(Arrays.asList("S1"), controller.listSatelliteIds()); + } + + @Test + public void testAddFileToDeviceInfoResponse() { + BlackoutController controller = new BlackoutController(); + + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + assert(controller.getInfo("DeviceA").getFiles().size() == 0); + controller.addFileToDevice("DeviceA", "filename", "contents"); + assert(controller.getInfo("DeviceA").getFiles().size() == 1); + } + + @Test + public void testInfoResponse() { + BlackoutController controller = new BlackoutController(); + + controller.createSatellite("Satellite1", "StandardSatellite", 314159, Angle.fromDegrees(310)); + EntityInfoResponse info = controller.getInfo("Satellite1"); + assert(info.getDeviceId().equals("Satellite1")); + assert(info.getPosition().equals(Angle.fromDegrees(310))); + assert(info.getHeight() == 314159); + assert(info.getType().equals("StandardSatellite")); + assert(info.getFiles().size() == 0); + } +} diff --git a/comp2511/blackout/tests/Task2Tests.java b/comp2511/blackout/tests/Task2Tests.java new file mode 100644 index 0000000..5e8d427 --- /dev/null +++ b/comp2511/blackout/tests/Task2Tests.java @@ -0,0 +1,206 @@ +package blackout; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import unsw.blackout.BlackoutController; +import unsw.blackout.FileTransferException; +import unsw.utils.Angle; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import static unsw.utils.MathsHelper.RADIUS_OF_JUPITER; + +@TestInstance(value = Lifecycle.PER_CLASS) +public class Task2Tests { + @Test + public void testDownloadSpeed() { + BlackoutController controller = new BlackoutController(); + + // The expected download speed should be (download speed / num transferring files), with the remainder ignored. + controller.createSatellite("Satellite1", "ShrinkingSatellite", 1000 + RADIUS_OF_JUPITER, Angle.fromDegrees(320)); + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + controller.createDevice("DeviceB", "LaptopDevice", Angle.fromDegrees(310)); + + String contents = "a relatively long string"; + controller.addFileToDevice("DeviceA", "file1", contents); + controller.addFileToDevice("DeviceB", "file2", contents); + + assertDoesNotThrow(() -> controller.sendFile("file1", "DeviceA", "Satellite1")); + assertDoesNotThrow(() -> controller.sendFile("file2", "DeviceB", "Satellite1")); + + // shrinking satellite is 15 bytes per tick, so should be 15/2 = 7. + controller.simulate(); + assertEquals(7, controller.getInfo("Satellite1").getFiles().get("file1").getData().length()); + assertEquals(7, controller.getInfo("Satellite1").getFiles().get("file2").getData().length()); + + // again, should be 14 + controller.simulate(); + assertEquals(14, controller.getInfo("Satellite1").getFiles().get("file1").getData().length()); + assertEquals(14, controller.getInfo("Satellite1").getFiles().get("file2").getData().length()); + } + + @Test + public void testDeleteFiles() { + BlackoutController controller = new BlackoutController(); + + // Files that are being transferred should be deleted if they are in transmission, and kept if they are not. + controller.createSatellite("Satellite1", "StandardSatellite", 1000 + RADIUS_OF_JUPITER, Angle.fromDegrees(310)); + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + + // Upload a file to the satellite, should be there after 1 tick. + controller.addFileToDevice("DeviceA", "file1", "1"); + assertDoesNotThrow(() -> controller.sendFile("file1", "DeviceA", "Satellite1")); + controller.simulate(); + assert(controller.getInfo("Satellite1").getFiles().size() == 1); + + // Upload another file, which will not transmit in time. + controller.addFileToDevice("DeviceA", "file2", "this string will take a fair amount of ticks to transmit"); + assertDoesNotThrow(() -> controller.sendFile("file2", "DeviceA", "Satellite1")); + controller.simulate(); + assert(controller.getInfo("Satellite1").getFiles().size() == 2); + + for (int i = 0; i < 50; ++i) { + controller.simulate(); + } + // At this point we should be occluded and out of range, + // while the file was in transmission - zero files should be present. + assert(controller.getInfo("Satellite1").getFiles().size() == 1); + } + + @Test + public void testTransientDeleteFile() { + BlackoutController controller = new BlackoutController(); + + // Files should NOT be deleted after occlusion or running out of distance. + controller.createSatellite("Satellite1", "ElephantSatellite", 1000 + RADIUS_OF_JUPITER, Angle.fromDegrees(330)); + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(310)); + + // Upload a file which will not transmit in time. + controller.addFileToDevice("DeviceA", "file1", "this string will take a fair amount of ticks to transmit but just to be sure"); + assertDoesNotThrow(() -> controller.sendFile("file1", "DeviceA", "Satellite1")); + controller.simulate(); + assert(controller.getInfo("Satellite1").getFiles().size() == 1); + assert(controller.getInfo("Satellite1").getFiles().get("file1").hasTransferCompleted() == false); + + // The file should NOT be deleted after this period. + // In addition the file should have transferred fully by this time. + for (int i = 0; i < 180; ++i) { + controller.simulate(); + } + assert(controller.getInfo("Satellite1").getFiles().size() == 1); + assert(controller.getInfo("Satellite1").getFiles().get("file1").hasTransferCompleted() == true); + } + + @Test + public void testRelayAccess() { + BlackoutController controller = new BlackoutController(); + + // We create two devices on one side of the planet, they should not be able to communicate. + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(180)); + controller.createDevice("DeviceB", "LaptopDevice", Angle.fromDegrees(0)); + assert(controller.communicableEntitiesInRange("DeviceA").size() == 0); + assert(controller.communicableEntitiesInRange("DeviceB").size() == 0); + + // We create a chain of relays that should connect the two devices. + int OFFSET = 15_000; + int NUM_SATELLITES = 5; + for (int i = 0; i < NUM_SATELLITES; ++i) { + controller.createSatellite("Satellite" + i, "RelaySatellite", OFFSET + RADIUS_OF_JUPITER, Angle.fromDegrees(180 - i * (180 / NUM_SATELLITES))); + } + + // We should be able to communicate with all relays, plus the other device. + assert(controller.communicableEntitiesInRange("DeviceA").size() == NUM_SATELLITES + 1); + assert(controller.communicableEntitiesInRange("DeviceB").size() == NUM_SATELLITES + 1); + } + + @Test + public void testCloudStorageDevice() { + BlackoutController controller = new BlackoutController(); + + // The size of the string in cloudstoragedevice should be the same in the satellite + // but larger after transfer into the laptop device. (Files are only decompressed + // inside devices (minus cloudstoragedevice). + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(180)); + controller.createDevice("DeviceB", "CloudStorageDevice", Angle.fromDegrees(180)); + controller.createSatellite("Satellite1", "ShrinkingSatellite", 10000 + RADIUS_OF_JUPITER, Angle.fromDegrees(180)); + + // Compression isn't guaranteed, but if we repeat digits we can improve our chances. + // Send the file to the satellite, it should be the same size as in the cloudstoragedevice. + controller.addFileToDevice("DeviceB", "file", "biiiiiiiiiiiiiiiiiiiiiiiig"); + assertDoesNotThrow(() -> controller.sendFile("file", "DeviceB", "Satellite1")); + controller.simulate(); // should arrive in two ticks + controller.simulate(); + assert(controller.getInfo("Satellite1").getFiles().get("file").getFileSize() == controller.getInfo("DeviceB").getFiles().get("file").getFileSize()); + + assertDoesNotThrow(() -> controller.sendFile("file", "Satellite1", "DeviceA")); + controller.simulate(); + // TODO make < + assert(controller.getInfo("Satellite1").getFiles().get("file").getFileSize() <= controller.getInfo("DeviceA").getFiles().get("file").getFileSize()); + } + + @Test + public void testSendFileExceptions() { + BlackoutController controller = new BlackoutController(); + + controller.createDevice("DeviceA", "LaptopDevice", Angle.fromDegrees(180)); + controller.createDevice("DeviceB", "LaptopDevice", Angle.fromDegrees(180)); + controller.createSatellite("Satellite1", "ShrinkingSatellite", 15000 + RADIUS_OF_JUPITER, Angle.fromDegrees(180)); + + // VirtualFileNotFoundException if the file doesn't exist on fromID + assertThrows(FileTransferException.VirtualFileNotFoundException.class, () -> controller.sendFile("?", "DeviceA", "Satellite1")); + // ... or it's a partial file. + controller.addFileToDevice("DeviceA", "file", "contents"); + assertDoesNotThrow(() -> controller.sendFile("file", "DeviceA", "Satellite1")); + assertThrows(FileTransferException.VirtualFileNotFoundException.class, () -> controller.sendFile("file", "Satellite1", "DeviceB")); + controller.simulate(); // make the file arrive + assert(controller.getInfo("Satellite1").getFiles().get("file").hasTransferCompleted()); + + // VirtualFileAlreadyExistsException if the file already exists on targetId. + assertThrows(FileTransferException.VirtualFileAlreadyExistsException.class, () -> controller.sendFile("file", "Satellite1", "DeviceA")); + // or if it's currently downloading + controller.addFileToDevice("DeviceA", "file1", "contents"); + assertDoesNotThrow(() -> controller.sendFile("file1", "DeviceA", "Satellite1")); + controller.simulate(); + assert(controller.getInfo("Satellite1").getFiles().get("file1").hasTransferCompleted()); + assertDoesNotThrow(() -> controller.sendFile("file1", "Satellite1", "DeviceB")); + assert(controller.getInfo("DeviceB").getFiles().get("file1").hasTransferCompleted() == false); + assertThrows(FileTransferException.VirtualFileAlreadyExistsException.class, () -> controller.sendFile("file1", "Satellite1", "DeviceB")); + controller.simulate(); // send all files + + // At this point our satellite has 0 files currently downloading and 2 files stored. + // VirtualFileNoBandwidthException if we are sending too many files. + // 15 bytes / tick = max of 15 files. + assertDoesNotThrow(() -> { + for (int i = 2; i < 15 + 2; ++i) { + controller.addFileToDevice("DeviceA", "file" + i, "contents"); + controller.sendFile("file" + i, "DeviceA", "Satellite1"); + } + }); + + controller.addFileToDevice("DeviceA", "too many files file", "contents"); + assertThrows(FileTransferException.VirtualFileNoBandwidthException.class, () -> controller.sendFile("too many files file", "DeviceA", "Satellite1")); + + // VirtualFileNoStorageSpaceException should throw if the lack of room was due to a max file cap + // max file cap of three for StandardSatellite, we have to be careful to avoid it's bandwidth limits + controller.createSatellite("Satellite2", "StandardSatellite", 15000 + RADIUS_OF_JUPITER, Angle.fromDegrees(180)); + assertDoesNotThrow(() -> { + for (int i = 0; i < 3; ++i) { + controller.addFileToDevice("DeviceA", "unique_file" + i, "1"); + controller.sendFile("unique_file" + i, "DeviceA", "Satellite2"); + controller.simulate(); + } + }); + + controller.addFileToDevice("DeviceA", "unique_file3", "contents"); + assertThrows(FileTransferException.VirtualFileNoStorageSpaceException.class, () -> controller.sendFile("unique_file3", "DeviceA", "Satellite2")); + + // ... or if we exceed the storage byte limit + controller.createSatellite("Satellite3", "StandardSatellite", 15000 + RADIUS_OF_JUPITER, Angle.fromDegrees(180)); + controller.addFileToDevice("DeviceA", "big_file", "a very long string that definitely exceeds the max byte storage amount of satellite3"); + assertThrows(FileTransferException.VirtualFileNoStorageSpaceException.class, () -> controller.sendFile("big_file", "DeviceA", "Satellite3")); + } +}
\ No newline at end of file diff --git a/comp2511/blackout/tests/TestHelpers.java b/comp2511/blackout/tests/TestHelpers.java new file mode 100644 index 0000000..913784b --- /dev/null +++ b/comp2511/blackout/tests/TestHelpers.java @@ -0,0 +1,14 @@ +package blackout; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.Collections; +import java.util.List; + +public class TestHelpers { + public static<T extends Comparable<? super T>> void assertListAreEqualIgnoringOrder(List<T> a, List<T> b) { + Collections.sort(a); + Collections.sort(b); + assertArrayEquals(a.toArray(), b.toArray()); + } +} |
