Skip to content
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

Programming exercises: Add MATLAB programming exercise template #10039

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from

Conversation

magaupp
Copy link
Contributor

@magaupp magaupp commented Dec 17, 2024

Checklist

General

Server

  • Important: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
  • I strictly followed the server coding and design guidelines.
  • I added multiple integration tests (Spring) related to the features (with a high test coverage).
  • I documented the Java code using JavaDoc style.

Changes affecting Programming Exercises

  • High priority: I tested all changes and their related features with all corresponding user types on a local server configured with the integrated lifecycle setup (LocalVC and LocalCI).

Motivation and Context

MATLAB requires a license to be run.

Description

This PR adds a MATLAB programming exercise template.

A LicenseService is added which provides environment variables with licensing information where required.
Licenses are configured in the application-*.yml files:

artemis:
    licenses:
        matlab:
            license-server: 1234@license-server

The ProgrammingExerciseBuildConfigService is updated to include these environment variables in its generated DockerRunConfig.

Docker container instantiation in BuildJobContainerService is updated to explicitly clear the ENTRYPOINT which results in more predictable behavior with its CMD. This is required if the docker image uses a ENTRYPOINT which does not run its ´CMD` in a shell.

The ProgrammingLanguageFeatureServices are updated to remove languages or project types which require a license if none is provided.

Steps for Testing

Prerequisites:

  • 1 Instructor
  • Matlab license server

Until the test server configuration is updated, this is only locally testable.

Testing locally requires a reachable license server.
TUM students may use the license server within the faculty network.
To find its address and port connect to lxhalle via SSH and read the /usr/applic/packages/matlab/licenses/network.lic file.
The license server is reachable via eduVPN or within eduroam.

Configure the license server in application-local.yml as shown above.

  1. Navigate to the programming exercise creation page
  2. Select MATLAB as the programming language
  3. Fill out the other required fields and create the exercise
  4. Wait until the builds finish
  5. Verify that the Template Result passes 0/3 tests without build failure
  6. Verify that the Solution Result passes 3/3 tests without build failure

Testserver States

Note

These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.







Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Server

Class/File Line Coverage Confirmation (assert/expect)
BuildJobContainerService.java 79%
LicenseConfiguration.java 100%
LicenseService.java 100%
ProgrammingExerciseBuildConfigService.java 83%
ProgrammingLanguageFeatureService.java 85%
ContinuousIntegrationService.java 100%
GitLabCIProgrammingLanguageFeatureService.java 100%
JenkinsProgrammingLanguageFeatureService.java 100%
LocalCIProgrammingLanguageFeatureService.java 100%

Summary by CodeRabbit

Here are the release notes for this pull request:

  • New Features

    • Added support for MATLAB as a programming language in Artemis
    • Introduced license configuration and management for MATLAB
    • Enhanced programming language feature services to include MATLAB
  • Documentation

    • Updated documentation to reflect MATLAB language support
    • Added README and template files for MATLAB exercises
  • Configuration

    • Added new configuration classes for managing MATLAB licenses
    • Updated programming language and feature services to support MATLAB
  • Testing

    • Implemented unit tests for MATLAB license and configuration services
    • Added test templates and test runner for MATLAB exercises

@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) documentation config-change Pull requests that change the config in a way that they require a deployment via Ansible. template buildagent Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module labels Dec 17, 2024
Copy link

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

@github-actions github-actions bot added the stale label Dec 25, 2024
@magaupp magaupp force-pushed the feature/programming-exercises/matlab-template branch from 6096857 to d2c1ba6 Compare December 29, 2024 14:23
@github-actions github-actions bot added core Pull requests that affect the corresponding module and removed stale labels Dec 29, 2024
@magaupp magaupp force-pushed the feature/programming-exercises/matlab-template branch from cc774a5 to 41a9a27 Compare December 30, 2024 23:51
@magaupp magaupp marked this pull request as ready for review January 1, 2025 21:01
@magaupp magaupp requested a review from a team as a code owner January 1, 2025 21:01
Copy link

coderabbitai bot commented Jan 1, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 pmd (7.8.0)
src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java

The following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration.

src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobContainerService.java

The following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration.

src/main/java/de/tum/cit/aet/artemis/core/config/LicenseConfiguration.java

The following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration.

  • 14 others

Walkthrough

This pull request introduces comprehensive support for MATLAB as a new programming language in the Artemis platform. The changes span multiple components, including configuration, services, documentation, and templates. Key modifications include adding MATLAB to the list of supported programming languages, creating a license configuration mechanism, updating programming language feature services, and providing MATLAB-specific exercise and test templates. The implementation ensures that MATLAB can be used for programming exercises while respecting its specific limitations and integration requirements.

Changes

File Path Change Summary
docs/user/exercises/programming-exercise-features.inc Added MATLAB support documentation, indicating Local CI compatibility and feature limitations
src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java Updated configuration properties to include LicenseConfiguration
src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java Added MATLAB enum value and updated ENABLED_LANGUAGES
src/main/webapp/app/entities/programming/programming-exercise.model.ts Added MATLAB to ProgrammingLanguage enum
src/main/resources/templates/matlab/ Added comprehensive MATLAB exercise, solution, and test templates

Suggested Labels

matlab, programming-language, feature-enhancement, documentation

Suggested Reviewers

  • BBesrour
  • JohannesStoehr
  • az108
  • SimonEntholzer

Sequence Diagram

sequenceDiagram
    participant User
    participant ProgrammingExercise
    participant LicenseService
    participant ContinuousIntegration

    User->>ProgrammingExercise: Create MATLAB Exercise
    ProgrammingExercise->>LicenseService: Check License
    LicenseService-->>ProgrammingExercise: License Status
    ProgrammingExercise->>ContinuousIntegration: Configure Build
    ContinuousIntegration-->>ProgrammingExercise: Build Configuration
    ProgrammingExercise-->>User: Exercise Ready
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (15)
src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java (1)

53-56: Check license conditions for MATLAB feature.

The overridden method correctly enumerates the ProgrammingLanguageFeature settings, including MATLAB. However, consider verifying that licensing is enforced in the relevant flow. Presently, the method does not conditionally disable or omit MATLAB if no license is available, which might lead to confusion for instructors/students without a valid license.

Also applies to: 68-76

src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java (1)

33-40: Consider adding MATLAB to the supported features if needed.
You are adding support for MATLAB in the broader PR, but it’s missing in this map. If GitLab CI is intended to support MATLAB, you might want to add a corresponding entry in this method.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeatureService.java (1)

90-91: License service check is straightforward.
If license checks become more complex in the future, consider caching or advanced logic to prevent repeated lookups.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseBuildConfigService.java (1)

82-94: Merging environment variables is well-structured.
Be mindful of potential key collisions; the license environment takes precedence.

src/main/resources/templates/matlab/exercise/finalGrade.m (1)

1-3: Implement finalGrade logic.
The placeholder is clear, but be sure to define how weighted grades are calculated and return the proper result.

Would you like help creating a sample implementation for this function?

src/main/resources/templates/matlab/exercise/averageGradeByStudent.m (1)

1-3: Add the average calculation logic.
The current placeholder lacks an implementation. Please define how to compute and return the average.

src/main/resources/templates/matlab/exercise/medianGradeByAssignment.m (1)

1-3: Consider renaming output variable and implementing median calculation logic.

The function name medianGradeByAssignment does not match the output variable named avg, which may cause confusion. Also, since the function is currently just a placeholder, consider implementing the logic to compute the median by assignment (e.g., using multiple rows or columns in grades) rather than returning a single median over the entire dataset.

src/main/resources/templates/matlab/solution/medianGradeByAssignment.m (1)

1-3: Ensure median is computed for each assignment, and rename output variable.

If your intent is to compute the median grade per assignment, consider leveraging the second parameter of MATLAB’s median function, for example, median(grades, 1) or median(grades, 2) depending on your data layout. Also, renaming the output variable from avg to something more descriptive (e.g., medGrades) can reduce confusion.

src/main/resources/templates/matlab/test/tests/GradeTest.m (1)

6-8: Empty TestClassSetup block
Although it’s perfectly fine to have an empty TestClassSetup block, confirm if any shared setup (e.g., path additions, fixture loading, or environment prep) is needed for MATLAB-based testing, especially since MATLAB usage may require licensed toolboxes or specific environment variables.

src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java (1)

248-248: Consider logging for future maintainability
Including a log statement right after this mock line would help maintainers quickly trace the container creation call flow for local CI tests.

src/main/webapp/app/exercises/programming/manage/programming-exercise-detail.component.ts (1)

251-252: Keep an eye on incorrect feature detection
The plagiarismCheckSupported property might be undefined for later-introduced languages, especially if no corresponding environment or meta configuration exists. Ensure the rest of the code gracefully handles the false fallback without unexpected UI states.

src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts (1)

365-365: Avoid re-initializing local properties within condition
In your logic for ProjectType.MAVEN_BLACKBOX versus PLAIN_MAVEN, repeating the assignment might confuse future maintainers. Consider simplifying with a single assignment or a small helper method that clarifies the allowed transitions.

src/main/resources/templates/aeolus/matlab/default.sh (3)

1-2: Enhance script robustness with additional safety flags.

Add -u and -o pipefail flags to catch unset variables and pipeline failures respectively.

 #!/usr/bin/env bash
-set -e
+set -euo pipefail

16-20: Pass arguments from main to test function.

The main function receives arguments but doesn't pass them to the test function.

 main () {
-  test
+  test "${@}"
 }

4-14: Add license validation before MATLAB execution.

Given that MATLAB requires a valid license, consider adding license validation before execution.

 test () {
   echo '⚙️ executing test'
+  # Verify license environment variables
+  if [ -z "${MATLAB_LICENSE_FILE:-}" ]; then
+    echo "❌ MATLAB license configuration is missing"
+    exit 1
+  fi
+
   cd "${testWorkingDirectory}"
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 6-6: testWorkingDirectory is referenced but not assigned.

(SC2154)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f37cb53 and 81d4966.

⛔ Files ignored due to path filters (3)
  • src/main/resources/config/application.yml is excluded by !**/*.yml
  • src/main/resources/templates/aeolus/matlab/default.yaml is excluded by !**/*.yaml
  • src/test/resources/config/application.yml is excluded by !**/*.yml
📒 Files selected for processing (38)
  • docs/user/exercises/programming-exercise-features.inc (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobContainerService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/config/LicenseConfiguration.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/LicenseService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseBuildConfigService.java (4 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeatureService.java (3 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java (4 hunks)
  • src/main/resources/templates/aeolus/matlab/default.sh (1 hunks)
  • src/main/resources/templates/matlab/exercise/.gitattributes (1 hunks)
  • src/main/resources/templates/matlab/exercise/.gitignore (1 hunks)
  • src/main/resources/templates/matlab/exercise/averageGradeByStudent.m (1 hunks)
  • src/main/resources/templates/matlab/exercise/finalGrade.m (1 hunks)
  • src/main/resources/templates/matlab/exercise/medianGradeByAssignment.m (1 hunks)
  • src/main/resources/templates/matlab/readme (1 hunks)
  • src/main/resources/templates/matlab/solution/.gitattributes (1 hunks)
  • src/main/resources/templates/matlab/solution/.gitignore (1 hunks)
  • src/main/resources/templates/matlab/solution/averageGradeByStudent.m (1 hunks)
  • src/main/resources/templates/matlab/solution/finalGrade.m (1 hunks)
  • src/main/resources/templates/matlab/solution/medianGradeByAssignment.m (1 hunks)
  • src/main/resources/templates/matlab/test/.gitattributes (1 hunks)
  • src/main/resources/templates/matlab/test/.gitignore (1 hunks)
  • src/main/resources/templates/matlab/test/testRunner.m (1 hunks)
  • src/main/resources/templates/matlab/test/tests/GradeTest.m (1 hunks)
  • src/main/webapp/app/entities/programming/programming-exercise.model.ts (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/programming-exercise-detail.component.ts (2 hunks)
  • src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts (2 hunks)
  • src/main/webapp/app/exercises/programming/shared/service/programming-language-feature/programming-language-feature.service.ts (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/core/config/LicenseConfigurationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/service/LicenseServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/util/ArgumentSources.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java (2 hunks)
✅ Files skipped from review due to trivial changes (6)
  • src/main/resources/templates/matlab/solution/.gitattributes
  • src/main/resources/templates/matlab/solution/.gitignore
  • src/main/resources/templates/matlab/test/.gitignore
  • src/main/resources/templates/matlab/test/.gitattributes
  • src/main/resources/templates/matlab/exercise/.gitattributes
  • src/main/resources/templates/matlab/exercise/.gitignore
🧰 Additional context used
📓 Path-based instructions (21)
src/main/webapp/app/entities/programming/programming-exercise.model.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/test/java/de/tum/cit/aet/artemis/programming/util/ArgumentSources.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/webapp/app/exercises/programming/manage/programming-exercise-detail.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeatureService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobContainerService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/webapp/app/exercises/programming/shared/service/programming-language-feature/programming-language-feature.service.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/config/LicenseConfiguration.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/core/config/LicenseConfigurationTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/LicenseService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseBuildConfigService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/programming/service/LicenseServiceTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

📓 Learnings (3)
src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java (1)
Learnt from: magaupp
PR: ls1intum/Artemis#9074
File: src/main/java/de/tum/in/www1/artemis/service/programming/TemplateUpgradePolicyService.java:35-35
Timestamp: 2024-11-12T12:51:46.554Z
Learning: The `defaultRepositoryUpgradeService` in the `TemplateUpgradePolicyService` is used as a default for all non-JAVA languages, with specialized services added based on testing outcomes if necessary.
src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java (1)
Learnt from: magaupp
PR: ls1intum/Artemis#9256
File: src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java:0-0
Timestamp: 2024-11-12T12:52:03.805Z
Learning: In `JenkinsProgrammingLanguageFeatureService.java`, comments explaining boolean flags in calls to the `ProgrammingLanguageFeature` constructor are unnecessary because the parameter names are clear, and most IDEs display them as inline hints.
src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java (1)
Learnt from: magaupp
PR: ls1intum/Artemis#8802
File: src/main/java/de/tum/in/www1/artemis/service/connectors/gitlabci/GitLabCIProgrammingLanguageFeatureService.java:24-24
Timestamp: 2024-11-12T12:51:46.554Z
Learning: Static code analysis for Rust in GitLab CI will be added in a follow-up PR.
🪛 Shellcheck (0.10.0)
src/main/resources/templates/aeolus/matlab/default.sh

[warning] 6-6: testWorkingDirectory is referenced but not assigned.

(SC2154)

🔇 Additional comments (67)
src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java (4)

14-14: MATLAB import is appropriate.

Importing MATLAB aligns with the new language support. No issues noted with naming or duplication.


30-32: EnumMap and Map usage is consistent.

Using EnumMap<ProgrammingLanguage, ProgrammingLanguageFeature> is optimal for managing a mapping keyed by enum types.


37-38: Dependency import is valid and clear.

Importing LicenseService satisfies the requirement for constructor injection. Good practice to inject the service.


49-51: Constructor injection is well-adhered.

The protected constructor with LicenseService parameter ensures consistent dependency injection, aligning with the "di:constructor_injection" guideline.

src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java (3)

42-44: Good use of constructor injection

Making the constructor protected here is acceptable if sub-classing is intended. If you want to prevent subclassing and only rely on Spring for instantiation, consider making it public or marking the class as final.


46-47: Method override is clearly defined

The override is well-structured, and the visibility is appropriate. This aligns with the single responsibility principle, as this service specifically provides the mapping of programming languages to their features.


Line range hint 49-66: Missing MATLAB entry and potential duplication

  1. The pull request mentions adding MATLAB support, but this method does not include an entry for the MATLAB programming language. Please verify whether MATLAB’s configuration should be part of this map.

  2. Each language feature definition has multiple boolean flags, leading to repetitive, verbose code. Consider a more data-driven or builder approach to reduce duplication and make the code easier to maintain.

src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java (3)

10-12: Imports look good.
No issues found with these added imports.


17-18: Domain and Service imports are appropriate.
These imports align with the domain model and service dependencies.


29-31: Protected constructor ensures controlled instantiation.
Making the constructor protected is valid if you only intend to instantiate or subclass it within the same package or its subclasses.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeatureService.java (5)

3-7: No issues with new imports.
All added imports appear relevant.


24-31: Constructor injection with LicenseService is sound.
Using constructor injection adheres to recommended DI patterns. However, it’s worth confirming whether protected scope is intentional rather than public for Spring bean creation.


32-32: Abstract method definition aligns with design.
Defining this method abstract enforces subclasses to provide their own feature configurations.


54-55: InfoContributor usage is correct.
Exposing language features through the builder is consistent with the endpoint’s purpose.


57-88: Efficient approach for selectively enabling features.
Using an EnumMap and filtering project types is an effective way to handle features per language.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseBuildConfigService.java (7)

6-6: HashMap import is fine.
It aligns with storing environment variables as key-value pairs.


21-21: Import for ProgrammingExercise is appropriate.
No issues with referencing the domain.


23-23: ProgrammingLanguage import is consistent with usage.
No issues found.


24-24: ProjectType import is needed for environment logic.
Looks good.


34-38: Constructor injection for LicenseService is consistent.
Matches the pattern of injecting dependencies for licensing checks.


59-80: Conditional logic for Docker flags is clear.
However, if partial flags or invalid network settings appear, ensure the function gracefully handles them.


97-112: Returning null for a missing network and environment might be risky.
Verify that downstream code can handle a null DockerRunConfig. Otherwise, consider returning a default instance.

src/main/resources/templates/matlab/solution/averageGradeByStudent.m (1)

1-3: Validate input dimensions and consider empty inputs.

Although the main logic for computing the average grade by student is sound, consider adding checks for empty or malformed input matrices. For example, handle cases where grades is empty or where the dimensions may be incorrect.

src/main/resources/templates/matlab/solution/finalGrade.m (1)

1-3: Confirm matrix dimensions and consider input validation.

The expression (grades * weights.').' transposes the result. Confirm that the chosen orientation (row vs. column) matches the intended usage. Also, consider validating that grades has a matching number of columns to the length of weights before attempting the multiplication.

src/main/resources/templates/matlab/test/testRunner.m (4)

1-2: Ensure MATLAB integration and paths are accessible
The import and blank line are straightforward, but remember that MATLAB must be installed on the runner environment. Verify that matlab.unittest.plugins.XMLPlugin is available and that the environment can run MATLAB tests without license conflicts.


3-4: Check the directory structure and correctness of the path
Confirm that the ${studentParentWorkingDirectoryName} path exists and is correctly set relative to this script’s location. Incorrect addpath usage can cause missing dependencies.


5-9: Runner and plugin usage look good
This setup for JUnit-compatible XML output is aligned with best practices for reporting. No issues here.


10-12: Finalize or re-check the suite name
Ensure the specified "tests" directory or suite name matches your file structure. If tests are nested in subfolders, consider adjusting the path.

src/main/java/de/tum/cit/aet/artemis/core/config/LicenseConfiguration.java (4)

1-2: Package declaration is correct
The package name matches the project structure for configuration classes.


10-11: Profile and property prefix
Using @Profile(PROFILE_CORE) and @ConfigurationProperties(prefix = "artemis.licenses") is a clean approach to separate license-related configs from other profiles.


14-16: Record usage is concise and appropriate
This record simplifies property handling for the MATLAB license server.


23-29: Nullable return approach
Returning null if the record is null is cautious and safe.

src/test/java/de/tum/cit/aet/artemis/programming/util/ArgumentSources.java (2)

4-4: Import for MATLAB
Explicitly importing MATLAB here is consistent with handling it as a separate case.


18-18: Ensuring MATLAB is in the unsupported list
Since Jenkins does not support MATLAB, adding MATLAB to the unsupported list is correct. This aligns with the PR goal to exclude MATLAB from Jenkins-based pipelines.

src/test/java/de/tum/cit/aet/artemis/core/config/LicenseConfigurationTest.java (3)

9-14: Test with valid license server
This is a straightforward test covering a typical scenario. Good use of assertThat for clarity.


16-20: Null record scenario
Properly tests defense against null in the constructor. This ensures safe default handling.


22-26: Null server value
Good coverage for the edge case where license server is present but null.

src/main/resources/templates/matlab/test/tests/GradeTest.m (3)

1-1: Great initial structure for a MATLAB test class
No issues spotted. The class extends matlab.unittest.TestCase, which is a recommended approach to organize tests in MATLAB.


13-19: Matrix initialization is correct
The grades matrix setup appears correct. If additional logic (e.g., randomized data for robust testing) is planned, consider factoring it into separate helper functions.


25-42: Comprehensive test coverage for grading functions
The three test methods cover median, average, and final grade calculations.

  • Confirm that these tests will complete successfully given the placeholder “TODO” in the underlying grade-related functions (if not yet fully implemented).
  • The AbsTol=0.0001 tolerance usage is good for floating-point comparisons.
src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java (1)

35-37: MATLAB integration with default upgrade service
By grouping MATLAB under the default repository upgrade service, you maintain consistency with other languages. This seems correct.

  • Consider verifying that the default upgrade service correctly accommodates any MATLAB-specific logic (e.g., copying .m files, ignoring hidden directories).
src/main/webapp/app/exercises/programming/shared/service/programming-language-feature/programming-language-feature.service.ts (1)

33-34: Allowing undefined return values for unsupported languages
Returning undefined is a safe design choice for missing features. Ensure that calling code handles undefined gracefully, especially since the rest of the code uses the result for UI behaviors.

src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java (1)

50-50: Enabling MATLAB in the supported languages set
Adding MATLAB to ENABLED_LANGUAGES is consistent with the rest of the PR and meets the new feature requirements.

src/test/java/de/tum/cit/aet/artemis/programming/service/LicenseServiceTest.java (5)

20-24: Tests reflect descriptive naming conventions and strong JUnit 5 usage
The test method name is clear, small, and uses assertThat appropriately. This aligns with the test guidelines requiring descriptive naming, small tests, and JUnit 5 features.


26-30: Ensures environment variables are not returned when no license is needed
This test thoroughly validates the service behavior for no-license-needed scenarios, following the principle of small and specific test coverage.


32-36: Properly checks MATLAB licensing requirement
The test ensures licensing logic for MATLAB is recognized. The test remains small and well-scoped, adhering to the coding guidelines.


38-42: Correctly verifies MATLAB environment variable setup
Ensuring that the returned environment map contains the expected MATLAB license key is a crucial test. Nice use of assertThat(environment).containsEntry(...).


44-50: Tests unlicensed MATLAB scenario elegantly
The test demonstrates a clear negative path for license checks, confirming that false is returned. This scenario-based approach is beneficial and meets the small-specific test guideline.

src/main/resources/templates/matlab/readme (4)

1-9: Clear exercise instructions
This section provides concise context about the grading matrix and sets clear expectations for the tasks ahead.


10-21: Well-structured task for median computation
The instructions for computing the median by assignment are sufficiently detailed, guiding students to implement the function properly.


23-33: Appropriate explanation for average grade by student
The textual guide clarifies input-output expectations, helping learners implement consistent logic.


36-49: Comprehensive description for final grade computation
The documentation clearly details the weighted average concept, including how to round results. This is well-organized for a typical MATLAB exercise readme.

src/main/java/de/tum/cit/aet/artemis/programming/service/LicenseService.java (3)

20-21: Scoped Spring bean profile
Annotating the service with @Profile(PROFILE_CORE) ensures that licensing logic is activated only in the intended environment, complying with single responsibility principles.


30-44: Simple and effective license check
The isLicensed method uses a straightforward condition to verify MATLAB license presence. It maintains readability and follows the KISS principle.


46-59: Avoids returning null by providing default environment
The getEnvironment method returns an immutable map, or an empty map when a license is not required. This is a clean approach respecting the best practice of returning empty collections rather than null.

src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java (2)

21-21: License configuration import
Importing LicenseConfiguration is consistent with the new licensing approach. This ensures all license-based properties are recognized by Spring Boot.


28-28: Proper inclusion of LicenseConfiguration in @EnableConfigurationProperties
Registers the properties class alongside other configurations, maintaining a cohesive configuration management pattern in Artemis.

src/main/webapp/app/entities/programming/programming-exercise.model.ts (1)

26-26: Add MATLAB enum entry: Good addition for expanded language support
Adding MATLAB in the ProgrammingLanguage enum appears consistent with the existing naming convention and structure.

src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java (2)

222-223: Include MATLAB in assignment path: Logical extension
Including MATLAB under "assignment" aligns with the approach used for other languages in this switch block.


233-233: Add MATLAB in test path: Maintains consistency
Matching MATLAB to the "tests" directory keeps the structure in sync with similar languages.

docs/user/exercises/programming-exercise-features.inc (2)

50-51: MATLAB in programming language support table
The newly added row correctly notes that MATLAB is supported in Local CI but not Jenkins, matching current platform capabilities.


96-97: MATLAB in feature support table
The row clearly indicates MATLAB’s feature limitations (sequential tests, static analysis, etc.). Documenting these constraints is helpful for instructors.

src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobContainerService.java (1)

111-111: Set entrypoint for improved container command behavior
Switching to .withEntrypoint().withCmd(...) ensures the container’s main process remains active until stop_container.txt is created. This is a solid approach for controlling container lifecycle.

src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java (1)

257-257: Check chaining consistency
The chained mock calls for .withEntrypoint() and .withCmd(...) look correct here. However, ensure that all other required container properties (like environment variables or volumes) are also appropriately mocked to avoid potential NullPointerExceptions in more complex test setups.

src/main/webapp/app/exercises/programming/manage/programming-exercise-detail.component.ts (1)

211-211: Ensure fallback logic for undefined features
Using optional chaining is good practice. As a next step, consider confirming through unit tests that the fallback (false) is sufficient whenever getProgrammingLanguageFeature returns undefined for certain edge cases (e.g., newly added languages not yet defined).

src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts (1)

276-276: Handle potential null from feature lookups
Forcing non-null with ! passes compilation but can lead to runtime errors if the service lookup fails to retrieve a feature. Safeguard by handling or warning if getProgrammingLanguageFeature might return undefined for certain incoming data.

src/main/resources/templates/aeolus/matlab/default.sh (1)

8-10: ⚠️ Potential issue

Review security implications of sudo operations.

The script performs several privileged operations that could pose security risks:

  1. Creating directories with sudo
  2. Changing ownership
  3. Removing a sudoers file (particularly concerning)

Consider:

  • Why does the sudoers file need to be removed?
  • Could these operations be performed with less privileged alternatives?

Let's verify the sudoers file usage:

Copy link
Contributor

@ole-ve ole-ve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot really comment on the matlab exercise, but the rest of the code looks good to me. Just added one question for clarification.

}

ProgrammingExercise exercise = buildConfig.getProgrammingExercise();
if (exercise == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When can this happen, i.e. what would be the reason when its null / not null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that some of the tests related to exercise importing set this to null. Not sure if this can happen in production code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
buildagent Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) config-change Pull requests that change the config in a way that they require a deployment via Ansible. core Pull requests that affect the corresponding module documentation programming Pull requests that affect the corresponding module ready for review server Pull requests that update Java code. (Added Automatically!) template tests
Projects
Status: Ready For Review
Status: In review
Development

Successfully merging this pull request may close these issues.

2 participants