Fakultas Ilmu Komputer UI

Commit abd696ae authored by Daya Adianto's avatar Daya Adianto
Browse files

Merge branch 'master' into 'master'

Publish exam problem sets from year 2021

See merge request !10
parents afadeeae 80dbe8be
Pipeline #89424 passed with stage
in 2 minutes and 11 seconds
---
include:
- template: Workflows/MergeRequest-Pipelines.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: DAST.gitlab-ci.yml
......@@ -9,21 +10,13 @@ stages:
- deploy
- dast
variables:
PIPENV_VENV_IN_PROJECT: 'True'
# Use merge request pipeline
workflow:
rules:
- if: '$CI_MERGE_REQUEST_IID'
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
build:
stage: build
image: docker.io/python:3.9.7-alpine
image: docker.io/python:3.10-alpine3.15
variables:
PIPENV_VERSION: 2021.5.29
PIPENV_VERSION: 2021.11.23
PIPENV_VENV_IN_PROJECT: 'True'
GIT_DEPTH: 0
before_script:
- apk add --no-cache git
- pip install pipenv==${PIPENV_VERSION}
......@@ -41,14 +34,30 @@ build:
paths:
- site/
deploy:
deploy:heroku:
stage: deploy
image: docker.io/alpine:3.14.2
image: docker.io/ruby:2.7.3-buster
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
needs:
- build
before_script:
- echo "Require HEROKU_API_KEY and HEROKU_APP environment variables"
- gem install dpl
script:
- dpl --provider=heroku --app=$HEROKU_APP --api-key=$HEROKU_API_KEY
cache: {}
dependencies: []
needs: []
environment:
name: heroku
url: https://pmpl-csui.herokuapp.com
deploy:production:
stage: deploy
image: docker.io/alpine:3.15.0
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PROJECT_NAMESPACE == "pmpl"'
before_script:
- echo "Require SSH_PRIVATE_KEY, SSH_KNOWN_HOSTS, SSH_USER, and SSH_HOST environment variables"
- apk add --no-cache openssh-client rsync
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- eval $(ssh-agent -s)
......@@ -56,18 +65,21 @@ deploy:
- echo "${SSH_KNOWN_HOSTS}" >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- rsync -ahP site/ admin@10.119.105.12:/opt/course-site
- rsync -ahP site/ "${SSH_USER}@${SSH_HOST}:/opt/course-site"
cache: {}
dependencies:
- build
environment:
name: production
url: https://pmpl.cs.ui.ac.id
dast:
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PROJECT_NAMESPACE == "pmpl"'
variables:
DAST_WEBSITE: 'https://pmpl.cs.ui.ac.id'
DAST_FULL_SCAN_ENABLED: 'true'
GIT_STRATEGY: 'none'
needs:
- deploy
- deploy:production
dependencies: []
......@@ -7,9 +7,8 @@ name = "pypi"
mkdocs = "~=1.2.3"
mkdocs-material = "~=7.3.6"
mkdocs-git-revision-date-localized-plugin = "~=0.10.2"
mkdocs-print-site-plugin = "~=2.1"
[dev-packages]
[requires]
python_version = "3.9"
python_version = "3.10"
{
"_meta": {
"hash": {
"sha256": "55e886b31815f880c164bb4265cb420b23cea1c56ecbb46f124d53be5309c314"
"sha256": "bdb4fafa25316842d7540f782922784cab09c7cb047ac8f540d7c62cbf7e7ca4"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
"python_version": "3.10"
},
"sources": [
{
......@@ -32,14 +32,6 @@
"markers": "python_version >= '3.6'",
"version": "==8.0.3"
},
"colorama": {
"hashes": [
"sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
"sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"
],
"markers": "platform_system == 'Windows'",
"version": "==0.4.4"
},
"ghp-import": {
"hashes": [
"sha256:5f8962b30b20652cdffa9c5a9812f7de6bcb56ec475acac579807719bf242c46",
......@@ -65,11 +57,11 @@
},
"importlib-metadata": {
"hashes": [
"sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100",
"sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb"
"sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6",
"sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"
],
"markers": "python_version < '3.10'",
"version": "==4.8.2"
"markers": "python_version >= '3.7'",
"version": "==4.10.0"
},
"jinja2": {
"hashes": [
......@@ -202,14 +194,6 @@
"markers": "python_version >= '3.6'",
"version": "==1.0.3"
},
"mkdocs-print-site-plugin": {
"hashes": [
"sha256:6b3c35d9c529dfb0aa5d0b95261c8ac954842a8b05993ce08b48e9006a1285ff",
"sha256:ffe52e87534798393840f96c950313f320b6e9effa9e47d21fce913d0f33dbb8"
],
"index": "pypi",
"version": "==2.1"
},
"packaging": {
"hashes": [
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
......@@ -320,14 +304,6 @@
"markers": "python_version >= '3.6'",
"version": "==5.0.0"
},
"typing-extensions": {
"hashes": [
"sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e",
"sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"
],
"markers": "python_version < '3.10'",
"version": "==4.0.1"
},
"watchdog": {
"hashes": [
"sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685",
......
# Interview Exam - Classloader-based Factory Pattern Implementation
> _Estimated time to read the description: 5 minutes_
>
> You may open Google, Stack Overflow, textbook, slides, etc.
> However, please be aware that your time is very limited.
> It is better to focus on doing the tasks.
The following code is taken from a research project named WinVMJ in the Reliable
Software Engineering lab at the Faculty of Computer Science Universitas Indonesia
with some modifications. The said code implements a factory design pattern used
for instantiating a type-compatible object dynamically using Java reflection
mechanism.
```java
// For brevity, assume all required classes have been imported.
public class FinancialReportFactory {
private static final Logger LOGGER = Logger.getLogger(FinancialReportFactory.class.getName());
private FinancialReportFactory() { }
public static FinancialReport create(String fullyQualifiedName, Object... base) {
FinancialReport obj = null;
try {
Class<?> clz = Class.forName(fullyQualifiedName);
Constructor<?> constructor = clz.getDeclaredConstructors()[0];
obj = (FinancialReport) constructor.newInstance(base);
} catch (IllegalArgumentException e) {
LOGGER.severe("Check the argument passed into the constructor");
System.exit(20);
} catch (ClassCastException e) {
LOGGER.severe("Cannot cast the object due to incompatible interface");
System.exit(30);
} catch (ClassNotFoundException e) {
LOGGER.severe("Class not found in the classloader");
System.exit(40);
} catch (Exception e) {
LOGGER.severe("Unknown, unhandled issue present in the method");
LOGGER.severe(e.toString());
System.exit(50);
}
return obj;
}
}
```
The factory implementation above expects two arguments: a fully qualified name
(FQN) of a class and a sequence of `Object` that required by a constructor method.
The FQN is a string that forms the identifier of a Java class in the classloader.
The other argument contains one or more objects of type `Object` that will be
passed into the constructor of a dynamically-loaded type via Java reflection
mechanism.
For example, if you have a Java class named `FooFinancialReport` located in a
package named `com.example`, then the FQN of `FooFinancialReport` class is
`com.example.FooFinancialReport`. If the said class require two arguments,
which is a string and an integer, then both argument also need to be prepared
before invoking the factory. One example of the invocation is as follows:
```java
public static void main(String[] args) {
Object[] requiredArgs = new Object[] {
"A financial report", new Integer(42)
};
FinancialReport example = FinancialReportFactory.create("com.example.FooFinancialReport", requiredArgs);
}
```
As you may have noticed, the factory also ensures that the created instance
has matching type named `FinancialReport`. In other words, the factory can
only create an object with type `FinancialReport` or any subtypes of it.
## Part 1: Input Space Partitioning
> _Estimated time to complete: 5 minutes_
You are asked to design an input space model for the factory method by following a functionality-based approach.
The information required to develop the model can be derived by reading the code
snippet and understanding the problem description. Once you have developed the
model, create the test requirement and the test cases.
Your tasks are as follows:
1. Determine the characteristics and the partition of the `create()` method.
2. Based on the input space model that you have created, create the test
requirement and the test cases based on certain coverage criteria chosen by
the proctor.
> Possible coverage criteria choices:
>
> - All Combinations Coverage (ACoC)
> - Each Choice Coverage (ECC)
> - Pair-Wise Coverage (PWC)
> - Base Choice Coverage (BCC)
>
> Note: **You do not have to write all test cases due to the time limit.**
> You need to demonstrate that the subset of your test cases valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 2: Graph Coverage
> _Estimated time to complete: 5 minutes_
You are asked to design a control flow graph (CFG), prepare the test requirement, and create the test paths.
Your tasks are as follows:
1. Create the CFG of the `create()` method.
2. Based on the CFG that you have created, create the test requirement and the
test paths based on certain coverage criteria chosen by the proctor.
> Possible coverage criteria choices:
>
> - Node Coverage (NC)
> - Edge Coverage (EC)
> - Edge-Pair Coverage (EPC)
>
> Note: **You do not have to write all test paths due to the time limit.**
> You need to demonstrate that the subset of your test paths valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 3: Discussion
> _Estimated time: 10 minutes_
You are asked to present your answers to the given problems and also to have
one-on-one interview with the proctor during the discussion time.
The list of topics that might be discussed is as follows:
- Code coverage (line coverage)
- Test-Driven Development (TDD)
- Test isolation
- Writing test cases in Java (JUnit)/Python (`unittest` and Django)/PHP
(PHPUnit)
- Your experience in conducting SQA activities in academics and/or work
environment
- The ideas of mutation testing
- CI/CD, especially in GitLab
- Monitoring
- And many more that may still related to SQA
## Acknowledgements
Credits to [Hanif Agung](https://gitlab.com/huggamugga) as the writer of the
[original code](https://gitlab.com/RSE-Lab-Fasilkom-UI/PricesIDE/vmj-aisco/-/blob/master/src/aisco.financialreport.core/aisco/financialreport/FinancialReportFactory.java)
used in this problem set.
# Interview Exam - CSV Reader
> _Estimated time to read the description: 5 minutes_
>
> You may open Google, Stack Overflow, textbook, slides, etc.
> However, please be aware that your time is very limited.
> It is better to focus on doing the tasks.
The following code is taken and modified from a mock exam problem set used in
Programming Foundations 2 course at the Faculty of Computer Science Universitas
Indonesia. The code contains a method named `read()` that accepts two arguments:
the filename and the regex pattern used for splitting a line into an array of
strings.
```java
// For brevity, assume all required classes have been imported.
public class CsvDataReader {
private static final Logger LOGGER = Logger.getLogger(CsvDataReader.class.getName());
private CsvDataReader() { }
public static List<String[]> read(String fileName, String regex) {
List<String[]> entries = new ArrayList<>();
File csvFile = new File(fileName);
try (Scanner in = new Scanner(csvFile)) {
String header = in.nextLine();
while (in.hasNextLine()) {
String line = in.nextLine();
String[] csvEntry = line.split(regex);
entries.add(csvEntry);
}
} catch (FileNotFoundException e) {
LOGGER.severe(String.format("%s not found", fileName));
LOGGER.severe("Immediately return an empty list");
return Collections.emptyList();
} catch (PatternSyntaxException e) {
LOGGER.severe(String.format("%s cannot be splitted using regex %s", line, regex));
LOGGER.severe("Immediately return an empty list");
return Collections.emptyList();
}
return entries;
}
}
```
The CSV reader implementation above attempts to read a file and tries to parse
each row read from the file using the given regex pattern in the tokenisation
process. Each row is parsed into an array of string and stored into a list.
The resulting list is then returned to the caller.
The implementation also contains some error handling. If the given file is not
found, then the method will return an empty list instead. Similarly, if there
is a line that cannot be splitted using the given regex pattern, then the
method will return an empty list.
## Part 1: Input Space Partitioning
> _Estimated time to complete: 5 minutes_
You are asked to design an input space model for the `read()` method by following a functionality-based approach.
The information required to develop the model can be derived by reading the code
snippet and understanding the problem description. Once you have developed the
model, create the test requirement and the test cases.
Your tasks are as follows:
1. Determine the characteristics and the partition of the `read()` method.
2. Based on the input space model that you have created, create the test
requirement and the test cases based on certain coverage criteria chosen by
the proctor.
> Possible coverage criteria choices:
>
> - All Combinations Coverage (ACoC)
> - Each Choice Coverage (ECC)
> - Pair-Wise Coverage (PWC)
> - Base Choice Coverage (BCC)
>
> Note: **You do not have to write all test cases due to the time limit.**
> You need to demonstrate that the subset of your test cases valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 2: Graph Coverage
> _Estimated time to complete: 5 minutes_
You are asked to design a control flow graph (CFG), prepare the test requirement, and create the test paths.
Your tasks are as follows:
1. Create the CFG of the `read()` method.
2. Based on the CFG that you have created, create the test requirement and the
test paths based on certain coverage criteria chosen by the proctor.
> Possible coverage criteria choices:
>
> - Node Coverage (NC)
> - Edge Coverage (EC)
> - Edge-Pair Coverage (EPC)
>
> Note: **You do not have to write all test paths due to the time limit.**
> You need to demonstrate that the subset of your test paths valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 3: Discussion
> _Estimated time: 10 minutes_
You are asked to present your answers to the given problems and also to have
one-on-one interview with the proctor during the discussion time.
The list of topics that might be discussed is as follows:
- Code coverage (line coverage)
- Test-Driven Development (TDD)
- Test isolation
- Writing test cases in Java (JUnit)/Python (`unittest` and Django)/PHP
(PHPUnit)
- Your experience in conducting SQA activities in academics and/or work
environment
- The ideas of mutation testing
- CI/CD, especially in GitLab
- Monitoring
- And many more that may still related to SQA
## Acknowledgements
Credits to [Jahns Christian Albert](https://gitlab.com/vanzrael) and the
teaching assistants of Programming Foundations 2 course for developing the [original code](https://gitlab.com/DDP2-CSUI/2020-gasal/simulasi-uas-2021_2022/-/blob/solusi/soal2/CsvDataSeeder.java)
used in this problem set.
# Interview Exam - Date Parser
> _Estimated time to read the description: 5 minutes_
>
> You may open Google, Stack Overflow, textbook, slides, etc.
> However, please be aware that your time is very limited.
> It is better to focus on doing the tasks.
The following code is taken and modified from Pacilkom Bot codebase, a bonus
project for Advanced Programming Even '17/'18. The code contains a method named
`parseDateParameter()` that accepts a string which will be parsed into an
instance of [`Map`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html).
```java
// For brevity, assume all required classes have been imported.
public class InputParser {
private static final Logger LOGGER = Logger.getLogger(InputParser.class.getName());
private DataParser() { }
public Map<String, String> parseDateParameter(String text) {
Map<String, String> result = new HashMap<>();
try {
if (text.isEmpty()) return result;
// Add new key value pair
String[] params = text.split(" ");
String[] keys = {"year", "term", "day"};
if (params.length == 3) result.put(keys[2], params[2]);
if (params.length == 2) result.put(keys[1], params[1]);
if (params.length == 1) result.put(keys[0], params[0]);
} catch (NullPointerException e) {
LOGGER.warning("User input text is null. Returning an empty list.");
} finally {
return result;
}
}
}
```
The implementation above attempts to parse a user input into a `Map` by
performing string tokenisation into an array of string parameters. Then, a
string parameter will be put into the `Map`. Specifically, the string parameter
at index position `0`, `1`, or `2` that will be put into the `Map`. The actual
position depends on the length of the array. Otherwise, if the number of string
parameters are zero or greater than three, then the `Map` will be empty and
returned to the caller.
In addition, the implementation also contains an error handling where the
method will return an empty `Map` if the input text is null.
## Part 1: Input Space Partitioning
> _Estimated time to complete: 5 minutes_
You are asked to design an input space model for the `parseDateParameter()`
method by following a functionality-based approach. The information required to
develop the model can be derived by reading the code snippet and understanding
the problem description. Once you have developed the model, create the test
requirement and the test cases.
Your tasks are as follows:
1. Determine the characteristics and the partition of the `parseDateParameter()` method.
2. Based on the input space model that you have created, create the test
requirement and the test cases based on certain coverage criteria chosen by
the proctor.
> Possible coverage criteria choices:
>
> - All Combinations Coverage (ACoC)
> - Each Choice Coverage (ECC)
> - Pair-Wise Coverage (PWC)
> - Base Choice Coverage (BCC)
>
> Note: **You do not have to write all test cases due to the time limit.**
> You need to demonstrate that the subset of your test cases valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 2: Graph Coverage
> _Estimated time to complete: 5 minutes_
You are asked to design a **control flow graph** (CFG), prepare the test
requirement, and create the test paths.
Your tasks are as follows:
1. Create the CFG of the `parseDateParameter()` method.
2. Based on the CFG that you have created, create the test requirement and the
test paths based on certain coverage criteria chosen by the proctor.
> Possible coverage criteria choices:
>
> - Node Coverage (NC)
> - Edge Coverage (EC)
> - Edge-Pair Coverage (EPC)
>
> Note: **You do not have to write all test paths due to the time limit.**
> You need to demonstrate that the subset of your test paths valid with the
> chosen coverage criteria.
Write your answer in a sheet of paper or Microsoft Word/Google Docs document.
You may include illustrations in your answer. Please prepare to present your
answer remotely via Zoom/Google Hangouts during discussion time.
## Part 3: Discussion
> _Estimated time: 10 minutes_
You are asked to present your answers to the given problems and also to have
one-on-one interview with the proctor during the discussion time.
The list of topics that might be discussed is as follows:
- Code coverage (line coverage)
- Test-Driven Development (TDD)
- Test isolation
- Writing test cases in Java (JUnit)/Python (`unittest` and Django)/PHP
(PHPUnit)
- Your experience in conducting SQA activities in academics and/or work
environment
- The ideas of mutation testing
- CI/CD, especially in GitLab
- Monitoring
- And many more that may still related to SQA
## Acknowledgements
Credits to [72-pacilkom-bot](https://gitlab.com/72pacil-chatbot) as a whole
for developing the [original code](https://gitlab.com/72pacil-chatbot/pacilkom-bot/-/blob/master/src/main/java/com/pacilkom/feats/siak/schedule/daily/DailyScheduleCommand.java)
used in this problem set.
......@@ -39,7 +39,7 @@ plugins:
- git-revision-date-localized:
type: iso_datetime
enable_creation_date: true
- print-site
fallback_to_build_date: true
markdown_extensions:
- abbr
......@@ -59,6 +59,9 @@ nav:
- Exercise 3: 2021/exercise3.md
- Exercise 4: 2021/exercise4.md
- Exercise 5: 2021/exercise5.md
- Interview Exam 1: 2021/exam1.md
- Interview Exam 2: 2021/exam2.md
- Interview Exam 3: 2021/exam3.md
- Year 2020: