-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
287 additions
and
29 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
35 changes: 35 additions & 0 deletions
35
algofi-compile/src/main/java/gooroommoon/algofi_compile/input/InputJudgeService.java
This file contains 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,35 @@ | ||
package gooroommoon.algofi_compile.input; | ||
|
||
import gooroommoon.algofi_compile.judge.service.JudgeService; | ||
import gooroommoon.algofi_compile.judge.service.language.CodeExecutor; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.nio.file.Path; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class InputJudgeService { | ||
private final JudgeService judgeService; | ||
|
||
public synchronized String judgeInput(String language, String code, String input){ | ||
CodeExecutor codeExecutor = judgeService.getCodeExecutor(language); | ||
|
||
Path path = codeExecutor.makeFileFromCode(code); | ||
|
||
Process process = judgeService.executeCode(codeExecutor, path); | ||
|
||
StringBuilder output = insertInputAndGetOutput(process, input, codeExecutor, path); | ||
|
||
return output.toString(); | ||
} | ||
|
||
private StringBuilder insertInputAndGetOutput(Process process, String input, CodeExecutor codeExecutor, Path path) { | ||
try { | ||
return judgeService.insertInputAndGetOutput(process, input); | ||
} finally { | ||
judgeService.destroy(process); | ||
codeExecutor.deleteFile(path); | ||
} | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -1,7 +1,2 @@ | ||
spring.datasource.url=jdbc:h2:tcp://localhost/~/test | ||
spring.datasource.driverClassName=org.h2.Driver | ||
spring.datasource.username=sa | ||
spring.datasource.password= | ||
|
||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect | ||
spring.jpa.hibernate.ddl-auto=update |
163 changes: 163 additions & 0 deletions
163
.../src/test/java/gooroommoon/algofi_compile/db/presentation/ProblemJudgeControllerTest.java
This file contains 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,163 @@ | ||
package gooroommoon.algofi_compile.db.presentation; | ||
|
||
import gooroommoon.algofi_compile.db.application.ProblemJudgeService; | ||
import gooroommoon.algofi_compile.db.domain.TestCaseRepository; | ||
import gooroommoon.algofi_compile.db.domain.entity.AlgorithmProblem; | ||
import gooroommoon.algofi_compile.db.domain.entity.TestCase; | ||
import gooroommoon.algofi_compile.db.presentation.dto.ProblemJudgeRequest; | ||
import gooroommoon.algofi_compile.db.presentation.dto.ProblemJudgeResponse; | ||
import gooroommoon.algofi_compile.judge.exception.CodeExecutionException; | ||
import gooroommoon.algofi_compile.judge.service.JudgeResult; | ||
import gooroommoon.algofi_compile.judge.service.JudgeService; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mock; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertAll; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.when; | ||
|
||
@SpringBootTest | ||
class ProblemJudgeControllerTest { | ||
|
||
@Mock | ||
private TestCaseRepository testCaseRepository; | ||
|
||
@Test | ||
void success() { | ||
//given | ||
AlgorithmProblem algorithmProblem = new AlgorithmProblem(1L, "문자 찾기","1","한 개의 문자열을 입력받고,특정 문자를 입력받아 해당 특정문자가 입력받은 문자열에 몇 개 존재하는지 알아내는 프로그램을 작성하세요. 대소문자를 구분하지 않습니다.문자열의 길이는 100을 넘지 않습니다.",10); | ||
TestCase testCase = new TestCase(1L, "computerprogramming r","3", algorithmProblem); | ||
when(testCaseRepository.findAllByAlgorithmProblemId(any())) | ||
.thenReturn(List.of(testCase)); | ||
|
||
JudgeService judgeService = new JudgeService(); | ||
|
||
ProblemJudgeService problemJudgeService = new ProblemJudgeService(testCaseRepository, judgeService); | ||
ProblemJudgeController problemJudgeController = new ProblemJudgeController(problemJudgeService); | ||
|
||
//when | ||
ProblemJudgeRequest request = new ProblemJudgeRequest(1L, "java", | ||
""" | ||
import java.util.Scanner; | ||
public class Main { | ||
public int solution(String str, char c){ | ||
int answer = 0; | ||
str = str.toUpperCase(); | ||
c = Character.toUpperCase(c); | ||
for(char x : str.toCharArray()){ | ||
if(x == c) answer++; | ||
} | ||
return answer; | ||
} | ||
public static void main(String[] args) { | ||
Scanner sc = new Scanner(System.in); | ||
Main T = new Main(); | ||
String str = sc.next(); | ||
char c = sc.next().charAt(0); | ||
System.out.println(T.solution(str, c)); | ||
} | ||
}"""); | ||
ResponseEntity<ProblemJudgeResponse> response = problemJudgeController.judgeProblem(request); | ||
assertThat(Objects.requireNonNull(response.getBody()).getMessage()).isEqualTo(JudgeResult.ACCEPTED.getMessage()); | ||
} | ||
|
||
@Test | ||
void concurrencyTest() throws InterruptedException { | ||
//given | ||
AlgorithmProblem algorithmProblem = new AlgorithmProblem(1L, "문자 찾기","1","한 개의 문자열을 입력받고,특정 문자를 입력받아 해당 특정문자가 입력받은 문자열에 몇 개 존재하는지 알아내는 프로그램을 작성하세요. 대소문자를 구분하지 않습니다.문자열의 길이는 100을 넘지 않습니다.",10); | ||
TestCase testCase = new TestCase(1L, "computerprogramming r","3", algorithmProblem); | ||
when(testCaseRepository.findAllByAlgorithmProblemId(any())) | ||
.thenReturn(List.of(testCase)); | ||
|
||
JudgeService judgeService = new JudgeService(); | ||
|
||
ProblemJudgeService problemJudgeService = new ProblemJudgeService(testCaseRepository, judgeService); | ||
ProblemJudgeController problemJudgeController = new ProblemJudgeController(problemJudgeService); | ||
|
||
int threadNum = 2; | ||
CountDownLatch doneSignal = new CountDownLatch(threadNum); | ||
ExecutorService executorService = Executors.newFixedThreadPool(threadNum); | ||
|
||
ProblemJudgeRequest request1 = new ProblemJudgeRequest(1L, "java", | ||
""" | ||
import java.util.Scanner; | ||
public class Main { | ||
public int solution(String str, char c){ | ||
int answer = 0; | ||
str = str.toUpperCase(); | ||
c = Character.toUpperCase(c); | ||
for(char x : str.toCharArray()){ | ||
if(x == c) answer++; | ||
} | ||
return answer; | ||
} | ||
public static void main(String[] args) { | ||
Scanner sc = new Scanner(System.in); | ||
Main T = new Main(); | ||
String str = sc.next(); | ||
char c = sc.next().charAt(0); | ||
System.out.println(T.solution(str, c)); | ||
} | ||
}"""); | ||
|
||
ProblemJudgeRequest request2 = new ProblemJudgeRequest(1L, "java", | ||
""" | ||
public class Main { | ||
public static void main(String[] args) { | ||
System.out.println(); | ||
} | ||
}"""); | ||
|
||
AtomicBoolean success1 = new AtomicBoolean(); | ||
AtomicBoolean success2 = new AtomicBoolean(); | ||
|
||
//when | ||
|
||
executorService.execute(() -> { | ||
try { | ||
problemJudgeController.judgeProblem(request1); | ||
success1.set(true); | ||
} catch (CodeExecutionException e) { | ||
success1.set(false); | ||
} finally { | ||
doneSignal.countDown(); | ||
} | ||
}); | ||
|
||
executorService.execute(() -> { | ||
try { | ||
problemJudgeController.judgeProblem(request2); | ||
success2.set(true); | ||
} catch (CodeExecutionException e) { | ||
success2.set(false); | ||
} finally { | ||
doneSignal.countDown(); | ||
} | ||
}); | ||
|
||
doneSignal.await(); | ||
executorService.shutdown(); | ||
|
||
//then | ||
assertAll( | ||
() -> assertThat(success1.get()).isTrue(), | ||
() -> assertThat(success2.get()).isFalse() | ||
); | ||
} | ||
} |
Oops, something went wrong.