-
Notifications
You must be signed in to change notification settings - Fork 0
test1 initial commit #4
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
Open
sharkovadarya
wants to merge
5
commits into
master
Choose a base branch
from
cw1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
a350c1e
cw1 initial commit (tests are currently not working)
sharkovadarya cb55814
added important comments to tests
sharkovadarya c5964f8
fixed tests
sharkovadarya 1593d44
Added annotations and minor fixes
sharkovadarya c16c975
Updated Main
sharkovadarya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <groupId>ru.spbau.group202.sharkova.cw1</groupId> | ||
| <artifactId>cw1</artifactId> | ||
| <version>1.0-SNAPSHOT</version> | ||
|
|
||
| <dependencies> | ||
| <!-- https://mvnrepository.com/artifact/junit/junit --> | ||
| <dependency> | ||
| <groupId>junit</groupId> | ||
| <artifactId>junit</artifactId> | ||
| <version>4.9</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.github.stefanbirkner</groupId> | ||
| <artifactId>system-rules</artifactId> | ||
| <version>1.16.0</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <!-- | ||
| https://mvnrepository.com/artifact/com.intellij/annotations | ||
| --> | ||
| <dependency> | ||
| <groupId>com.intellij</groupId> | ||
| <artifactId>annotations</artifactId> | ||
| <version>12.0</version> | ||
| </dependency> | ||
|
|
||
|
|
||
| <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> | ||
| <dependency> | ||
| <groupId>org.mockito</groupId> | ||
| <artifactId>mockito-all</artifactId> | ||
| <version>1.10.19</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| <properties> | ||
| <maven.compiler.target>1.8</maven.compiler.target> | ||
| <maven.compiler.source>1.8</maven.compiler.source> | ||
| </properties> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>com.zenjava</groupId> | ||
| <artifactId>javafx-maven-plugin</artifactId> | ||
| <version>8.8.3</version> | ||
| <configuration> | ||
| <mainClass>your.package.with.Launcher</mainClass> | ||
| </configuration> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
|
|
||
|
|
||
| </project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package ru.spbau.group202.cw1; | ||
|
|
||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Path; | ||
| import java.security.NoSuchAlgorithmException; | ||
|
|
||
| /** | ||
| * Instances of this abstract class calculate MD5 check-sum of a directory. | ||
| */ | ||
| abstract public class MD5Hasher { | ||
| protected final static int BUFFER_SIZE = 4096; | ||
|
|
||
| /** | ||
| * This method calculates MD5 check-sum of a file or a directory. | ||
| * @param path path to file/directory | ||
| * @return byte[] array storing MD5 check-sum | ||
| */ | ||
| @NotNull | ||
| public abstract byte[] getHashFromPath(@NotNull Path path) throws IOException, NoSuchAlgorithmException; | ||
| } | ||
85 changes: 85 additions & 0 deletions
85
cw1/src/main/java/ru/spbau/group202/cw1/MD5MultiThread.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| package ru.spbau.group202.cw1; | ||
|
|
||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.security.DigestInputStream; | ||
| import java.security.MessageDigest; | ||
| import java.security.NoSuchAlgorithmException; | ||
| import java.util.ArrayList; | ||
| import java.util.concurrent.ForkJoinPool; | ||
| import java.util.concurrent.RecursiveTask; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| /** | ||
| * This implementation of MD5Hasher abstract class uses a ForkJoinPool | ||
| * to compute MD5 check-sum. | ||
| */ | ||
| public class MD5MultiThread extends MD5Hasher { | ||
|
|
||
| private ForkJoinPool pool; | ||
|
|
||
| public MD5MultiThread(int numberOfThreads) { | ||
| pool = new ForkJoinPool(numberOfThreads); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| @NotNull | ||
| public byte[] getHashFromPath(@NotNull Path path) throws IOException, NoSuchAlgorithmException { | ||
| MessageDigest md5 = MessageDigest.getInstance("MD5"); | ||
| if (Files.isDirectory(path)) { | ||
| processDirectory(path, md5); | ||
| } else { | ||
| processFile(path, md5); | ||
| } | ||
|
|
||
| return md5.digest(); | ||
| } | ||
|
|
||
| private void processDirectory(@NotNull Path path, @NotNull MessageDigest md) throws IOException { | ||
| md.update(path.getFileName().toString().getBytes()); | ||
| ArrayList<RecursiveTask<byte[]>> tasks = new ArrayList<>(); | ||
| for (Path p : Files.walk(path).filter(Files::isRegularFile).collect(Collectors.toList())) { | ||
| RecursiveTask<byte[]> task = new RecursiveTask<byte[]>() { | ||
| @Override | ||
| protected byte[] compute() { | ||
| try { | ||
| return getHashFromPath(p); | ||
| } catch (Exception e) { | ||
| // TODO handle exceptions | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ага, todo :) |
||
| } | ||
| return null; | ||
| } | ||
| }; | ||
| tasks.add(task); | ||
| pool.execute(task); | ||
| } | ||
|
|
||
| for (RecursiveTask<byte[]> task : tasks) { | ||
| try { | ||
| byte[] hash = task.get(); | ||
| if (hash == null) { | ||
| throw new IOException("Unable to compute"); | ||
| } | ||
| md.update(hash); | ||
| } catch (Exception e) { | ||
| throw new IOException("ForkJoinPool exception; unable to compute."); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void processFile(@NotNull Path path, @NotNull MessageDigest md) throws IOException { | ||
| try (DigestInputStream stream = new DigestInputStream(Files.newInputStream(path), md)) { | ||
| byte[] buf = new byte[BUFFER_SIZE]; | ||
| while (stream.read(buf) != -1) { | ||
| ; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| } | ||
42 changes: 42 additions & 0 deletions
42
cw1/src/main/java/ru/spbau/group202/cw1/MD5SingleThread.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package ru.spbau.group202.cw1; | ||
|
|
||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.security.DigestInputStream; | ||
| import java.security.MessageDigest; | ||
| import java.security.NoSuchAlgorithmException; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| /** | ||
| * This implementation of MD5Hasher abstract class calculates MD5 check-sum | ||
| * in a regular way, using a single thread. | ||
| */ | ||
| public class MD5SingleThread extends MD5Hasher { | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| @NotNull | ||
| public byte[] getHashFromPath(@NotNull Path path) throws IOException, NoSuchAlgorithmException { | ||
| MessageDigest md5 = MessageDigest.getInstance("MD5"); | ||
| if (Files.isDirectory(path)) { | ||
| md5.update(path.getFileName().toString().getBytes()); | ||
| for (Path p : Files.walk(path).filter(Files::isRegularFile).collect(Collectors.toList())) { | ||
| md5.update(getHashFromPath(p)); | ||
| } | ||
|
|
||
| return md5.digest(); | ||
| } | ||
|
|
||
| try (DigestInputStream stream = new DigestInputStream(Files.newInputStream(path), md5)) { | ||
| byte[] buf = new byte[BUFFER_SIZE]; | ||
| while (stream.read(buf) != -1) { | ||
| ; | ||
| } | ||
| return stream.getMessageDigest().digest(); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package ru.spbau.group202.cw1; | ||
|
|
||
| import javax.xml.bind.DatatypeConverter; | ||
| import java.nio.file.Paths; | ||
|
|
||
| public class Main { | ||
| public static void main(String[] args) { | ||
| if (args.length < 1) { | ||
| System.out.println("Incorrect usage; specify filepaths."); | ||
| return; | ||
| } | ||
|
|
||
| MD5MultiThread concurrentHasher = new MD5MultiThread(4); | ||
| MD5SingleThread regularHasher = new MD5SingleThread(); | ||
| for (String path : args) { | ||
| System.out.println(path + ":"); | ||
| try { | ||
| long start = System.currentTimeMillis(); | ||
| byte[] res = regularHasher.getHashFromPath(Paths.get(path)); | ||
| System.out.println(DatatypeConverter.printHexBinary(res)); | ||
| long diff1 = System.currentTimeMillis() - start; | ||
| System.out.println("Single-thread computation: " + diff1 + " ms."); | ||
|
|
||
| start = System.currentTimeMillis(); | ||
| res = concurrentHasher.getHashFromPath(Paths.get(path)); | ||
| System.out.println(DatatypeConverter.printHexBinary(res)); | ||
| long diff2 = System.currentTimeMillis() - start; | ||
| System.out.println("Multi-thread computation: " + diff2 + " ms."); | ||
|
|
||
| System.out.println("\n The difference is " + (diff1 - diff2) + " ms.\n"); | ||
| } catch (Exception e) { | ||
| if (e.getMessage() != null) { | ||
| System.out.println(e.getMessage()); | ||
| } else { | ||
| System.out.println("Unable to compute md5 of this file"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
100 changes: 100 additions & 0 deletions
100
cw1/src/test/java/ru/spbau/group202/cw1/MD5HasherTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| package ru.spbau.group202.cw1; | ||
|
|
||
| import org.junit.Test; | ||
|
|
||
| import javax.xml.bind.DatatypeConverter; | ||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.nio.file.Path; | ||
| import java.security.NoSuchAlgorithmException; | ||
|
|
||
| import static org.junit.Assert.*; | ||
|
|
||
| // IMPORTANT: testEmptyDir will only work if you create 'dir' directory manually | ||
| // git doesn't allow empty directories to be committed | ||
|
|
||
| /** | ||
| * This class tests correctness of MD5Hasher implementations methods | ||
| */ | ||
| public class MD5HasherTest { | ||
|
|
||
| private final static int numberOfThreads = 4; | ||
|
|
||
| // create 'dir' directory manually! | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| private void testEmptyDir(MD5Hasher hasher) throws NoSuchAlgorithmException, IOException { | ||
| File file = new File("src/test/resources/testdir/dir"); | ||
| Path path = file.toPath(); | ||
| byte[] hash = hasher.getHashFromPath(path); | ||
| String str = DatatypeConverter.printHexBinary(hash); | ||
| // this md5 checksum was calculated here: http://progs.be/md5.html | ||
| assertEquals("736007832d2167baaae763fd3a3f3cf1", str.toLowerCase()); | ||
| } | ||
|
|
||
| private void testEmptyFile(MD5Hasher hasher) throws NoSuchAlgorithmException, IOException { | ||
| File file = new File("src/test/resources/testdir/file2.txt"); | ||
| Path path = file.toPath(); | ||
| byte[] hash = hasher.getHashFromPath(path); | ||
| String str = DatatypeConverter.printHexBinary(hash); | ||
| // this md5 checksum was calculated here: http://onlinemd5.com/ | ||
| assertEquals("D41D8CD98F00B204E9800998ECF8427E", str); | ||
| } | ||
|
|
||
| private void testNonEmptyFile(MD5Hasher hasher) throws NoSuchAlgorithmException, IOException { | ||
| File file = new File("src/test/resources/testdir/file1.txt"); | ||
| Path path = file.toPath(); | ||
| byte[] hash = hasher.getHashFromPath(path); | ||
| String str = DatatypeConverter.printHexBinary(hash); | ||
| // this md5 checksum was calculated here: http://onlinemd5.com/ | ||
| assertEquals("40A5D58FFA6E88AA578D6683AC413105", str); | ||
| } | ||
|
|
||
| @Test | ||
| public void testEmptyDirRegularHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5SingleThread hasher = new MD5SingleThread(); | ||
| testEmptyDir(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testEmptyDirConcurrentHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5MultiThread hasher = new MD5MultiThread(numberOfThreads); | ||
| testEmptyDir(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testEmptyFileRegularHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5SingleThread hasher = new MD5SingleThread(); | ||
| testEmptyFile(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testEmptyFileConcurrentHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5MultiThread hasher = new MD5MultiThread(numberOfThreads); | ||
| testEmptyFile(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testNonEmptyFileRegularHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5SingleThread hasher = new MD5SingleThread(); | ||
| testNonEmptyFile(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testNonEmptyFileConcurrentHasher() throws NoSuchAlgorithmException, IOException { | ||
| MD5MultiThread hasher = new MD5MultiThread(numberOfThreads); | ||
| testNonEmptyFile(hasher); | ||
| } | ||
|
|
||
| @Test | ||
| public void testEqualResultsSingleAndMultiThread() throws NoSuchAlgorithmException, IOException { | ||
| MD5SingleThread regularHasher = new MD5SingleThread(); | ||
| MD5MultiThread concurrentHasher = new MD5MultiThread(numberOfThreads); | ||
|
|
||
| File file = new File("src/test/resources/testdir"); | ||
| Path path = file.toPath(); | ||
| byte[] hash = regularHasher.getHashFromPath(path); | ||
| String str1 = DatatypeConverter.printHexBinary(hash); | ||
| hash = concurrentHasher.getHashFromPath(path); | ||
| String str2 = DatatypeConverter.printHexBinary(hash); | ||
| assertEquals(str1, str2); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| filefile |
Empty file.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
исключения тоже бы хорошо документировать