DeleteRepoJob.java

1
package edu.ucsb.cs156.frontiers.jobs;
2
3
import edu.ucsb.cs156.frontiers.entities.Course;
4
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
5
import edu.ucsb.cs156.frontiers.services.RepositoryService;
6
import edu.ucsb.cs156.frontiers.services.RepositoryService.GithubRepository;
7
import edu.ucsb.cs156.frontiers.services.jobs.JobContext;
8
import edu.ucsb.cs156.frontiers.services.jobs.JobContextConsumer;
9
import java.util.List;
10
import java.util.Optional;
11
import lombok.Builder;
12
13
@Builder
14
public class DeleteRepoJob implements JobContextConsumer {
15
  Long courseId;
16
  String prefix;
17
  CourseRepository courseRepository;
18
  RepositoryService repositoryService;
19
20
  @Override
21
  public Course getCourse() {
22
    Optional<Course> courseOpt = courseRepository.findById(courseId);
23 1 1. getCourse : replaced return value with null for edu/ucsb/cs156/frontiers/jobs/DeleteRepoJob::getCourse → KILLED
    return courseOpt.orElse(null);
24
  }
25
26
  @Override
27
  public void accept(JobContext ctx) throws Exception {
28
    ctx.log(String.format("Starting delete repository job for course ID: %s", courseId));
29
    ctx.log(String.format("prefix=%s", prefix));
30
31
    Optional<Course> courseOpt = courseRepository.findById(courseId);
32 1 1. accept : negated conditional → KILLED
    if (courseOpt.isEmpty()) {
33
      ctx.log(String.format("ERROR: Course with ID %s not found", courseId));
34
      return;
35
    }
36
37
    Course course = courseOpt.get();
38 2 1. accept : negated conditional → KILLED
2. accept : negated conditional → KILLED
    if (course.getOrgName() == null || course.getInstallationId() == null) {
39
      ctx.log("ERROR: Course has no linked GitHub organization");
40
      return;
41
    }
42
43
    List<GithubRepository> repositories;
44
    int errors = 0;
45
    try {
46
      repositories = repositoryService.getRepositoriesMatchingPrefix(course, prefix);
47
    } catch (Exception e) {
48
      ctx.log(String.format("ERROR: Failed to list repositories: %s", e.getMessage()));
49 1 1. accept : Changed increment from 1 to -1 → KILLED
      errors++;
50
      ctx.log(String.format("Summary: found=0, deleted=0, retained=0, errors=%d", errors));
51
      return;
52
    }
53
54
    int deleted = 0;
55
    int retained = 0;
56
57
    for (GithubRepository repository : repositories) {
58
      try {
59
        boolean deletedRepository =
60
            repositoryService.deleteRepositoryIfEmpty(course, repository.name());
61 1 1. accept : negated conditional → KILLED
        if (deletedRepository) {
62 1 1. accept : Changed increment from 1 to -1 → KILLED
          deleted++;
63
          ctx.log(String.format("Deleted empty repository: %s", repository.name()));
64
        } else {
65 1 1. accept : Changed increment from 1 to -1 → KILLED
          retained++;
66
          ctx.log(String.format("Retained repository with commits: %s", repository.name()));
67
        }
68
      } catch (Exception e) {
69 1 1. accept : Changed increment from 1 to -1 → KILLED
        errors++;
70
        ctx.log(
71
            String.format(
72
                "ERROR: Failed to delete/check repository %s: %s",
73
                repository.name(), e.getMessage()));
74
      }
75
    }
76
77
    ctx.log(
78
        String.format(
79
            "Summary: found=%d, deleted=%d, retained=%d, errors=%d",
80
            repositories.size(), deleted, retained, errors));
81
    ctx.log("Done");
82
  }
83
}

Mutations

23

1.1
Location : getCourse
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_getCourse_returnsCourse_whenFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/jobs/DeleteRepoJob::getCourse → KILLED

32

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_courseNotFound()]
negated conditional → KILLED

38

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_courseWithOrgNameButNoInstallationId()]
negated conditional → KILLED

2.2
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_githubApiErrorDuringList()]
negated conditional → KILLED

49

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_githubApiErrorDuringList()]
Changed increment from 1 to -1 → KILLED

61

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_githubApiErrorDuringDeleteOrCheck()]
negated conditional → KILLED

62

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_githubApiErrorDuringDeleteOrCheck()]
Changed increment from 1 to -1 → KILLED

65

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_someReposRetainedBecauseCommitsExist()]
Changed increment from 1 to -1 → KILLED

69

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.DeleteRepoJobTests]/[method:test_accept_githubApiErrorDuringDeleteOrCheck()]
Changed increment from 1 to -1 → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0