Skip to content

Commit 38aadc9

Browse files
committed
Merge branch 'developer'
2 parents 3782b37 + 1ada515 commit 38aadc9

File tree

23 files changed

+127
-32
lines changed

23 files changed

+127
-32
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# ALEX 1.5.1
2+
3+
This release only contains some bug fixes.
4+
5+
16
# ALEX 1.5.0
27

38
## Breaking Changes

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Make sure you have Java 8 installed on your system.
1818
We advise to use a modern web browser like Google Chrome, Mozilla Firefox or Microsoft Edge with JavaScript enabled.
1919

2020
1. [Download](https://github.com/LearnLib/alex/releases/latest) the latest version.
21-
2. Open a terminal and start ALEX via `java -jar alex-1.5.0.war [--alex.port=XXXX]`.
21+
2. Open a terminal and start ALEX via `java -jar alex-1.5.1.war [--alex.port=XXXX]`.
2222
3. Wait until the command line prints something like `de.learnlib.alex.App - Started App in XX.XXX seconds`.
2323
3. Open *http://localhost:8000* in a web browser.
2424

@@ -48,7 +48,7 @@ cd alex
4848
mvn install package [-DskipTests]
4949
```
5050

51-
The bundle can then be found at `build/target/alex-build-1.5.0.war`.
51+
The bundle can then be found at `build/target/alex-build-1.5.1.war`.
5252

5353
## Further reading
5454

backend/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<parent>
2424
<groupId>de.learnlib.alex</groupId>
2525
<artifactId>alex-parent</artifactId>
26-
<version>1.5.0</version>
26+
<version>1.5.1</version>
2727
<relativePath>../pom.xml</relativePath>
2828
</parent>
2929

backend/src/main/java/de/learnlib/alex/data/dao/ProjectDAOImpl.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import de.learnlib.alex.learning.entities.LearnerResult;
2727
import de.learnlib.alex.learning.repositories.LearnerResultRepository;
2828
import de.learnlib.alex.testing.entities.TestSuite;
29+
import de.learnlib.alex.testing.repositories.TestReportRepository;
2930
import org.apache.logging.log4j.LogManager;
3031
import org.apache.logging.log4j.Logger;
3132
import org.apache.logging.log4j.Marker;
@@ -68,6 +69,9 @@ public class ProjectDAOImpl implements ProjectDAO {
6869
/** The repository for learner results. */
6970
private LearnerResultRepository learnerResultRepository;
7071

72+
/** The repository for test reports. */
73+
private TestReportRepository testReportRepository;
74+
7175
/** The FileDAO to use. Will be injected. */
7276
private FileDAO fileDAO;
7377

@@ -85,14 +89,17 @@ public class ProjectDAOImpl implements ProjectDAO {
8589
* The FileDAO to use.
8690
* @param projectUrlDAO
8791
* The ProjectUrlDAO to use.
92+
* @param testReportRepository
93+
* The repository for test reports.
8894
*/
8995
@Inject
9096
public ProjectDAOImpl(ProjectRepository projectRepository, LearnerResultRepository learnerResultRepository,
91-
@Lazy FileDAO fileDAO, @Lazy ProjectUrlDAO projectUrlDAO) {
97+
TestReportRepository testReportRepository, @Lazy FileDAO fileDAO, @Lazy ProjectUrlDAO projectUrlDAO) {
9298
this.projectRepository = projectRepository;
9399
this.learnerResultRepository = learnerResultRepository;
94100
this.fileDAO = fileDAO;
95101
this.projectUrlDAO = projectUrlDAO;
102+
this.testReportRepository = testReportRepository;
96103
}
97104

98105
@Override
@@ -111,6 +118,10 @@ public Project create(final Project project) throws ValidationException {
111118
testSuite.setProject(project);
112119
project.getTests().add(testSuite);
113120

121+
if (project.getUrls().isEmpty()) {
122+
throw new ValidationException("The project has to have at least one URL.");
123+
}
124+
114125
project.getUrls().forEach(url -> {
115126
url.setId(null);
116127
url.setProject(project);
@@ -164,6 +175,10 @@ public Project update(User user, Project project) throws NotFoundException, Vali
164175
.collect(Collectors.toList());
165176
projectUrlDAO.checkAccess(user, project, urls);
166177

178+
if (project.getUrls().isEmpty()) {
179+
throw new ValidationException("The project has to have at least one URL.");
180+
}
181+
167182
try {
168183
project.setUser(user);
169184
project.setGroups(projectInDb.getGroups());
@@ -204,6 +219,8 @@ public void delete(User user, Long projectId) throws NotFoundException {
204219
final Project project = projectRepository.findOne(projectId);
205220
checkAccess(user, project);
206221

222+
testReportRepository.deleteAllByProject_Id(projectId);
223+
learnerResultRepository.deleteAllByProject_Id(projectId);
207224
projectRepository.delete(project);
208225

209226
// delete the project directory

backend/src/main/java/de/learnlib/alex/learning/repositories/LearnerResultRepository.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,15 @@ public interface LearnerResultRepository extends JpaRepository<LearnerResult, UU
116116
@SuppressWarnings("checkstyle:methodname")
117117
Long deleteByProject_IdAndTestNoIn(Long projectId, Long... testNos);
118118

119+
/**
120+
* Delete all learner results in a project.
121+
*
122+
* @param projectId
123+
* The ID of the project.
124+
* @return The amount of deleted LearnResults.
125+
*/
126+
@Transactional
127+
@SuppressWarnings("checkstyle:methodname")
128+
Long deleteAllByProject_Id(Long projectId);
129+
119130
}

backend/src/main/java/de/learnlib/alex/learning/rest/LearnerResource.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public Response resume(@PathParam("project_id") long projectId,
269269
* This will always return OK, even if there is nothing to stop.
270270
* To see if there is currently a learning process, the status like '/active' will be returned.
271271
*
272-
* @param projectId The project to stop.
272+
* @param projectId The project to stop.
273273
* @return The status of the current learn process.
274274
* @successResponse 200 OK
275275
* @responseType de.learnlib.alex.learning.entities.LearnerStatus
@@ -281,8 +281,14 @@ public Response stop(@PathParam("project_id") long projectId) {
281281
User user = ((UserPrincipal) securityContext.getUserPrincipal()).getUser();
282282
LOGGER.traceEntry("stop() for user {}.", user);
283283

284+
try {
285+
projectDAO.getByID(user.getId(), projectId);
286+
} catch (NotFoundException e) {
287+
return ResourceErrorHandler.createRESTErrorMessage("LearnerResource.stop", Status.NOT_FOUND, e);
288+
}
289+
284290
if (learner.isActive(projectId)) {
285-
learner.stop(user); // Hammer Time
291+
learner.stop(projectId); // Hammer Time
286292
} else {
287293
LOGGER.info(RESOURCE_MARKER, "tried to stop the learning again.");
288294
}
@@ -297,17 +303,16 @@ public Response stop(@PathParam("project_id") long projectId) {
297303
*
298304
* @param projectId The project to get the Status of.
299305
* @return The information of the learning
300-
* @throws NotFoundException If the previous learn job or the related Project could not be found.
301306
* @successResponse 200 OK
302307
* @responseType de.learnlib.alex.learning.entities.LearnerResult
303308
* @errorResponse 404 not found `de.learnlib.alex.common.utils.ResourceErrorHandler.RESTError
304309
*/
305310
@GET
306311
@Path("/{project_id}/status")
307312
@Produces(MediaType.APPLICATION_JSON)
308-
public Response getResult(@PathParam("project_id") long projectId) throws NotFoundException {
313+
public Response getStatus(@PathParam("project_id") long projectId) {
309314
User user = ((UserPrincipal) securityContext.getUserPrincipal()).getUser();
310-
LOGGER.traceEntry("getResult() for user {}.", user);
315+
LOGGER.traceEntry("getStatus() for user {}.", user);
311316

312317
LearnerStatus status = learner.getStatus(projectId);
313318

backend/src/main/java/de/learnlib/alex/learning/services/Learner.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,11 @@ private void validateCounterexample(User user, LearnerResumeConfiguration config
331331
/**
332332
* Ends the learning process after the current step.
333333
*
334-
* @param user The user that wants to stop his active thread.
334+
* @param projectId The id of the project that is learned.
335335
*/
336-
public void stop(User user) {
337-
final AbstractLearnerThread learnerThread = userThreads.get(user);
336+
public void stop(Long projectId) {
337+
final AbstractLearnerThread learnerThread = userThreads.get(projectId);
338+
338339
if (learnerThread != null) {
339340
learnerThread.stopLearning();
340341
}

backend/src/main/java/de/learnlib/alex/testing/repositories/TestReportRepository.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,15 @@ public interface TestReportRepository extends JpaRepository<TestReport, Long> {
4848
@Transactional(readOnly = true)
4949
@SuppressWarnings("checkstyle:methodname")
5050
List<TestReport> findAllByProject_Id(Long projectId);
51+
52+
/**
53+
* Delete all test reports by project id.
54+
*
55+
* @param projectId
56+
* The id of the project.
57+
* @return The number of deleted test reports.
58+
*/
59+
@Transactional
60+
@SuppressWarnings("checkstyle:methodname")
61+
Long deleteAllByProject_Id(Long projectId);
5162
}

backend/src/test/java/de/learnlib/alex/data/dao/ProjectDAOImplTest.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import de.learnlib.alex.data.entities.SymbolGroup;
2424
import de.learnlib.alex.data.repositories.ProjectRepository;
2525
import de.learnlib.alex.learning.repositories.LearnerResultRepository;
26+
import de.learnlib.alex.testing.repositories.TestReportRepository;
2627
import org.hamcrest.MatcherAssert;
2728
import org.junit.Before;
2829
import org.junit.Test;
@@ -35,6 +36,7 @@
3536
import javax.persistence.RollbackException;
3637
import javax.validation.ConstraintViolationException;
3738
import javax.validation.ValidationException;
39+
import java.util.Collections;
3840
import java.util.HashSet;
3941
import java.util.LinkedList;
4042
import java.util.List;
@@ -65,11 +67,15 @@ public class ProjectDAOImplTest {
6567
@Mock
6668
private ProjectUrlDAO projectUrlDAO;
6769

70+
@Mock
71+
private TestReportRepository testReportRepository;
72+
6873
private ProjectDAO projectDAO;
6974

7075
@Before
7176
public void setUp() {
72-
projectDAO = new ProjectDAOImpl(projectRepository, learnerResultRepository, fileDAO, projectUrlDAO);
77+
projectDAO = new ProjectDAOImpl(projectRepository, learnerResultRepository, testReportRepository, fileDAO,
78+
projectUrlDAO);
7379
}
7480

7581
@Test
@@ -91,6 +97,30 @@ public void shouldCreateAValidEmptyProject() {
9197
assertThat(p.getId(), is(equalTo(1L)));
9298
}
9399

100+
@Test(expected = ValidationException.class)
101+
public void shouldNotCreateAProjectIfUrlsAreEmpty() throws NotFoundException {
102+
User user = new User(USER_ID);
103+
104+
Project project = new Project();
105+
project.setId(PROJECT_ID);
106+
project.setUser(user);
107+
108+
projectDAO.create(project);
109+
}
110+
111+
@Test(expected = ValidationException.class)
112+
public void shouldNotUpdateAProjectIfUrlsAreEmpty() throws NotFoundException {
113+
User user = new User(USER_ID);
114+
115+
Project project = new Project();
116+
project.setId(PROJECT_ID);
117+
project.setUser(user);
118+
119+
given(projectRepository.findOne(PROJECT_ID)).willReturn(project);
120+
121+
projectDAO.update(user, project);
122+
}
123+
94124
@Test
95125
public void shouldCreateAValidPreFilledProject() {
96126
SymbolGroup testGroup = new SymbolGroup();
@@ -111,6 +141,7 @@ public void shouldCreateAValidPreFilledProject() {
111141
@Test(expected = ValidationException.class)
112142
public void shouldHandleConstraintViolationExceptionOnProjectCreationGracefully() {
113143
Project project = new Project();
144+
project.setUrls(Collections.singletonList(new ProjectUrl()));
114145
//
115146
given(projectRepository.save(project)).willThrow(ConstraintViolationException.class);
116147

@@ -120,6 +151,7 @@ public void shouldHandleConstraintViolationExceptionOnProjectCreationGracefully(
120151
@Test(expected = ValidationException.class)
121152
public void shouldHandleDataIntegrityViolationExceptionOnProjectCreationGracefully() {
122153
Project project = new Project();
154+
project.setUrls(Collections.singletonList(new ProjectUrl()));
123155
//
124156
given(projectRepository.save(project)).willThrow(DataIntegrityViolationException.class);
125157

@@ -129,6 +161,7 @@ public void shouldHandleDataIntegrityViolationExceptionOnProjectCreationGraceful
129161
@Test(expected = ValidationException.class)
130162
public void shouldHandleTransactionSystemExceptionOnProjectCreationGracefully() {
131163
Project project = new Project();
164+
project.setUrls(Collections.singletonList(new ProjectUrl()));
132165
//
133166
ConstraintViolationException constraintViolationException;
134167
constraintViolationException = new ConstraintViolationException("Project is not valid!", new HashSet<>());
@@ -218,6 +251,7 @@ public void shouldHandleConstraintViolationExceptionOnProjectUpdateGracefully()
218251
user.setId(USER_ID);
219252

220253
Project project = new Project();
254+
project.setUrls(Collections.singletonList(new ProjectUrl()));
221255
project.setUser(user);
222256
project.setId(PROJECT_ID);
223257

@@ -235,6 +269,7 @@ public void shouldHandleDataIntegrityViolationExceptionOnProjectUpdateGracefully
235269
Project project = new Project();
236270
project.setUser(user);
237271
project.setId(PROJECT_ID);
272+
project.setUrls(Collections.singletonList(new ProjectUrl()));
238273

239274
given(projectRepository.save(project)).willThrow(DataIntegrityViolationException.class);
240275
given(projectRepository.findOne(PROJECT_ID)).willReturn(project);
@@ -248,6 +283,7 @@ public void shouldHandleTransactionSystemExceptionOnProjectUpdateGracefully() th
248283
user.setId(USER_ID);
249284

250285
Project project = new Project();
286+
project.setUrls(Collections.singletonList(new ProjectUrl()));
251287
project.setUser(user);
252288
project.setId(PROJECT_ID);
253289

backend/src/test/java/de/learnlib/alex/learning/rest/LearnerResourceTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ public void shouldStopIfTheLearningIsActive() {
297297
Response response = target("/learner/" + PROJECT_TEST_ID + "/stop").request().header("Authorization", adminToken).get();
298298

299299
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
300-
verify(learner).stop(admin);
300+
verify(learner).stop(PROJECT_TEST_ID);
301301
}
302302

303303
@Test
@@ -312,7 +312,7 @@ public void shouldNotStopIfTheLearningIsNotActive() {
312312
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
313313
String expectedJSON = "{\"active\":false}";
314314
assertEquals(expectedJSON, response.readEntity(String.class));
315-
verify(learner, never()).stop(admin);
315+
verify(learner, never()).stop(PROJECT_TEST_ID);
316316
}
317317

318318
@Test

0 commit comments

Comments
 (0)