From fa1d1c206b93d45445e90ab3004783f925cfe9a7 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Fri, 20 Aug 2021 01:46:23 +0200 Subject: [PATCH 01/18] Selenium --- pom.xml | 10 +++ src/main/resources/templates/calculator.html | 8 +- .../e2e/MultiplicationJourneyE2ETest.java | 73 +++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java diff --git a/pom.xml b/pom.xml index 0c27268..6aa21e1 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,16 @@ javax.inject 1 + + org.seleniumhq.selenium + selenium-java + test + + + io.github.bonigarcia + webdrivermanager + 3.7.1 + calculator diff --git a/src/main/resources/templates/calculator.html b/src/main/resources/templates/calculator.html index 9174951..277575c 100644 --- a/src/main/resources/templates/calculator.html +++ b/src/main/resources/templates/calculator.html @@ -28,10 +28,10 @@

- +
- @@ -39,12 +39,12 @@

- +
- +
diff --git a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java new file mode 100644 index 0000000..aff1351 --- /dev/null +++ b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java @@ -0,0 +1,73 @@ +package tech.zerofiltre.testing.calcul.e2e; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class MultiplicationJourneyE2ETest { + + @LocalServerPort + private int port; + + private WebDriver webDriver; + private String baseUrl; + + @BeforeAll + static void setUpFireFoxDriver() { + WebDriverManager.firefoxdriver().setup(); + } + + @BeforeEach + void setUpWebDriver() { + webDriver = new FirefoxDriver(); + baseUrl = "http://localhost:" + port + "/calculator"; + + } + + @AfterEach + void quitWebDriver() { + if (webDriver != null) { + webDriver.quit(); + } + } + + @Test + void multiplyTwoBySixteenMustReturn32(){ + + //GIVEN + webDriver.get(baseUrl); + WebElement leftField = webDriver.findElement(By.id("left")); + WebElement typeDropDown = webDriver.findElement(By.id("type")); + WebElement rightField = webDriver.findElement(By.id("right")); + WebElement submitButton = webDriver.findElement(By.id("submit")); + + //WHEN + leftField.sendKeys("2"); + typeDropDown.sendKeys("x"); + rightField.sendKeys("16"); + submitButton.click(); + + //THEN + WebDriverWait waiter = new WebDriverWait(webDriver,5); + WebElement solutionElement = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("solution"))); + String solution = solutionElement.getText(); + assertThat(solution).isEqualTo("32"); + } + + +} From 4799acc0b2013bd8ac0e9156961a9d44b2b60f80 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Fri, 20 Aug 2021 23:17:48 +0200 Subject: [PATCH 02/18] Add specific project maven settings --- .m2/settings.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .m2/settings.xml diff --git a/.m2/settings.xml b/.m2/settings.xml new file mode 100644 index 0000000..510e0ba --- /dev/null +++ b/.m2/settings.xml @@ -0,0 +1,18 @@ + + + org.sonarsource.scanner.maven + + + + sonar + + true + + + + http://localhost:9000 + + + + + \ No newline at end of file From c52fc4f6ee2cffda3f0425edc0b7bf8174054fb3 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Fri, 20 Aug 2021 23:44:28 +0200 Subject: [PATCH 03/18] Corect code smells --- .../testing/calcul/domain/Calculator.java | 8 +- .../controller/CalculatorControllerSIT.java | 4 +- .../testing/calcul/domain/CalculatorTest.java | 34 +-- .../domain/ConversionCalculatorTest.java | 10 +- .../calcul/domain/DoubleCalculatorTest.java | 6 +- .../domain/StatisticsCalculatorTest.java | 8 +- .../service/BatchCalculatorServiceTest.java | 12 +- .../calcul/service/CalculatorServiceIT.java | 33 ++- .../calcul/service/CalculatorServiceTest.java | 234 +++++++++--------- .../calcul/service/SolutionFormatterTest.java | 30 +-- 10 files changed, 190 insertions(+), 189 deletions(-) diff --git a/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java b/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java index 6492e44..afe011e 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java @@ -4,10 +4,14 @@ import java.util.Set; import javax.inject.Named; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Named public class Calculator { + Logger logger = LoggerFactory.getLogger(Calculator.class); + public int add(int a, int b) { return a + b; } @@ -54,12 +58,12 @@ public void longCalculation() { try { Thread.sleep(500); } catch (final InterruptedException e) { - e.printStackTrace(); + logger.debug("Thread has been interrupted", e); } } public Set digitsSet(int number) { - final Set integers = new HashSet(); + final Set integers = new HashSet<>(); final String numberString = String.valueOf(number); for (int i = 0; i < numberString.length(); i++) { diff --git a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java index 382bbe7..b81b853 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java @@ -22,7 +22,7 @@ @WebMvcTest(controllers = { CalculatorController.class, CalculatorService.class }) @ExtendWith(SpringExtension.class) -public class CalculatorControllerSIT { +class CalculatorControllerSIT { @Inject private MockMvc mockMvc; @@ -34,7 +34,7 @@ public class CalculatorControllerSIT { private Calculator calculator; @Test - public void givenACalculatorApp_whenRequestToAdd_thenSolutionIsShown() throws Exception { + void givenACalculatorApp_whenRequestToAdd_thenSolutionIsShown() throws Exception { // GIVEN when(calculator.add(2, 3)).thenReturn(5); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java index 7ef7a90..c72844e 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java @@ -27,7 +27,7 @@ import org.junit.jupiter.params.provider.ValueSource; @ExtendWith(LoggingExtension.class) -public class CalculatorTest { +class CalculatorTest { private static Instant startedAt; @@ -40,25 +40,25 @@ public void setLogger(Logger logger) { } @BeforeEach - public void initCalculator() { + void initCalculator() { logger.info("Appel avant chaque test"); calculatorUnderTest = new Calculator(); } @AfterEach - public void undefCalculator() { + void undefCalculator() { logger.info("Appel après chaque test"); calculatorUnderTest = null; } @BeforeAll - public static void initStartingTime() { + static void initStartingTime() { System.out.println("Appel avant tous les tests"); startedAt = Instant.now(); } @AfterAll - public static void showTestDuration() { + static void showTestDuration() { System.out.println("Appel après tous les tests"); final Instant endedAt = Instant.now(); final long duration = Duration.between(startedAt, endedAt).toMillis(); @@ -66,7 +66,7 @@ public static void showTestDuration() { } @Test - public void testAddTwoPositiveNumbers() { + void testAddTwoPositiveNumbers() { // Arrange final int a = 2; final int b = 3; @@ -80,7 +80,7 @@ public void testAddTwoPositiveNumbers() { } @Test - public void multiply_shouldReturnTheProduct_ofTwoIntegers() { + void multiply_shouldReturnTheProduct_ofTwoIntegers() { // Arrange final int a = 42; final int b = 11; @@ -94,7 +94,7 @@ public void multiply_shouldReturnTheProduct_ofTwoIntegers() { @ParameterizedTest(name = "{0} x 0 doit être égal à 0") @ValueSource(ints = { 1, 2, 42, 1011, 5089 }) - public void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { + void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { // Arrange -- Tout est prêt ! // Act -- Multiplier par zéro @@ -106,7 +106,7 @@ public void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { @ParameterizedTest(name = "{0} + {1} doit être égal à {2}") @CsvSource({ "1,1,2", "2,3,5", "42,57,99" }) - public void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int expectResult) { + void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int expectResult) { // Arrange -- Tout est prêt ! // Act @@ -118,7 +118,7 @@ public void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int ex @Timeout(1) @Test - public void longCalcul_shouldComputeInLessThan1Second() { + void longCalcul_shouldComputeInLessThan1Second() { // Arrange // Act @@ -129,7 +129,7 @@ public void longCalcul_shouldComputeInLessThan1Second() { } @Test - public void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { + void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { // GIVEN final int number = 95897; @@ -143,14 +143,14 @@ public void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { } @Test - public void listDigits_shouldReturnsTheListOfDigits_ofNegativeInteger() { + void listDigits_shouldReturnsTheListOfDigits_ofNegativeInteger() { final int number = -124432; final Set actualDigits = calculatorUnderTest.digitsSet(number); assertThat(actualDigits).containsExactlyInAnyOrder(1, 2, 3, 4); } @Test - public void listDigits_shouldReturnsTheListOfZero_ofZero() { + void listDigits_shouldReturnsTheListOfZero_ofZero() { final int number = 0; final Set actualDigits = calculatorUnderTest.digitsSet(number); assertThat(actualDigits).containsExactly(0); @@ -158,7 +158,7 @@ public void listDigits_shouldReturnsTheListOfZero_ofZero() { @Disabled("Stoppé car cela échoue tous les mardis") @Test - public void testDate() { + void testDate() { // GIVEN final LocalDateTime dateTime = LocalDateTime.now(); @@ -169,7 +169,7 @@ public void testDate() { } @Test - public void fact12_shouldReturnsTheCorrectAnswer() { + void fact12_shouldReturnsTheCorrectAnswer() { // GIVEN final int number = 12; @@ -182,7 +182,7 @@ public void fact12_shouldReturnsTheCorrectAnswer() { } @Test - public void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { + void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { // GIVEN final int cacheFactorial = 479001600; @@ -194,7 +194,7 @@ public void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { } @Test - public void multiplyAndDivide_shouldBeIdentity() { + void multiplyAndDivide_shouldBeIdentity() { // GIVEN final Random r = new Random(); final int a = 1 + r.nextInt(100); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java index 1fb80e8..188e0a8 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java @@ -12,7 +12,7 @@ @Tag("ConversionTests") @DisplayName("Réussir à convertir entre différentes unités.") -public class ConversionCalculatorTest { + class ConversionCalculatorTest { private ConversionCalculator calculatorUnderTest = new ConversionCalculator(); @@ -22,14 +22,14 @@ public class ConversionCalculatorTest { class TemperatureTests { @Test @DisplayName("Soit une T° à 0°C, lorsque l'on convertit en °F, alors on obtient 32°F.") - public void celsiusToFahrenheit_returnsAFahrenheitTempurature_whenCelsiusIsZero() { + void celsiusToFahrenheit_returnsAFahrenheitTempurature_whenCelsiusIsZero() { Double actualFahrenheit = calculatorUnderTest.celsiusToFahrenheit(0.0); assertThat(actualFahrenheit).isCloseTo(32.0, withinPercentage(0.01)); } @Test @DisplayName("Soit une T° à 32°F, lorsque l'on convertit en °C, alors on obtient 0°C.") - public void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { + void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { Double actualCelsius = calculatorUnderTest.fahrenheitToCelsius(32.0); assertThat(actualCelsius).isCloseTo(0.0, withinPercentage(0.01)); } @@ -37,14 +37,14 @@ public void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { @Test @DisplayName("Soit un volume de 3.78541 litres, en gallons, on obtient 1 gallon.") - public void litresToGallons_returnsOneGallon_whenConvertingTheEquivalentLitres() { + void litresToGallons_returnsOneGallon_whenConvertingTheEquivalentLitres() { Double actualLitres = calculatorUnderTest.litresToGallons(3.78541); assertThat(actualLitres).isCloseTo(1.0, withinPercentage(0.01)); } @Test @DisplayName("L'aire d'un disque de rayon 1 doit valoir PI.") - public void radiusToAreaOfCircle_returnsPi_whenWeHaveARadiusOfOne() { + void radiusToAreaOfCircle_returnsPi_whenWeHaveARadiusOfOne() { Double actualArea = calculatorUnderTest.radiusToAreaOfCircle(1.0); assertThat(actualArea).isCloseTo(PI, withinPercentage(0.01)); } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java index 31abf37..4ea6adf 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java @@ -4,17 +4,17 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -public class DoubleCalculatorTest { + class DoubleCalculatorTest { private Calculator calculatorUnderTest; @BeforeEach - public void initCalculator() { + void initCalculator() { calculatorUnderTest = new Calculator(); } @Test @Disabled("Test ambigu et hors limite du type double") - public void subTwoDoubleNumbers_shouldReturnsTheCorrectAnswer() { + void subTwoDoubleNumbers_shouldReturnsTheCorrectAnswer() { // GIVEN // WHEN diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java index a798cd2..06df414 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java @@ -16,7 +16,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class StatisticsCalculatorTest { + class StatisticsCalculatorTest { @Spy IntSummaryStatistics summaryStatistics = new IntSummaryStatistics(); @@ -24,12 +24,12 @@ public class StatisticsCalculatorTest { StatisticsCalculator underTest; @BeforeEach - public void setUp() { + void setUp() { underTest = new StatisticsCalculator(summaryStatistics); } @Test - public void average_shouldSample_allIntegersProvided() { + void average_shouldSample_allIntegersProvided() { final ArgumentCaptor sampleCaptor = ArgumentCaptor.forClass(Integer.class); final List samples = Arrays.asList(2, 8, 5, 3, 7); @@ -41,7 +41,7 @@ public void average_shouldSample_allIntegersProvided() { } @Test - public void average_shouldReturnTheMean_ofAListOfIntegers() { + void average_shouldReturnTheMean_ofAListOfIntegers() { final List samples = Arrays.asList(2, 8, 5, 3, 7); final Integer result = underTest.average(samples); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java index 55f708f..89e9b91 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java @@ -25,7 +25,7 @@ import tech.zerofiltre.testing.calcul.domain.model.CalculationType; @ExtendWith(MockitoExtension.class) -public class BatchCalculatorServiceTest { + class BatchCalculatorServiceTest { @Mock CalculatorService calculatorService; @@ -35,7 +35,7 @@ public class BatchCalculatorServiceTest { BatchCalculatorService batchCalculatorServiceNoMock; @BeforeEach - public void init() { + void init() { batchCalculatorService = new BatchCalculatorServiceImpl(calculatorService); batchCalculatorServiceNoMock = new BatchCalculatorServiceImpl( @@ -44,7 +44,7 @@ public void init() { } @Test - public void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList() + void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList() throws IOException, URISyntaxException { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); @@ -57,7 +57,7 @@ public void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList( } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectArguments() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectArguments() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); final ArgumentCaptor calculationModelCaptor = ArgumentCaptor.forClass(CalculationModel.class); @@ -79,7 +79,7 @@ public void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectAr } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); when(calculatorService.calculate(any(CalculationModel.class))) @@ -113,7 +113,7 @@ public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAns } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer2() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer2() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); when(calculatorService.calculate(any(CalculationModel.class))) diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java index 18f204b..dc6a2c3 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java @@ -3,29 +3,28 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; - import tech.zerofiltre.testing.calcul.domain.Calculator; import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; import tech.zerofiltre.testing.calcul.domain.model.CalculationType; -public class CalculatorServiceIT { +class CalculatorServiceIT { - // Mettre en place des objets réels non mockés - private final Calculator calculator = new Calculator(); - private final SolutionFormatter formatter = new SolutionFormatterImpl(); + // Mettre en place des objets réels non mockés + private final Calculator calculator = new Calculator(); + private final SolutionFormatter formatter = new SolutionFormatterImpl(); - // Initialiser la classe à tester - private final CalculatorService underTest = new CalculatorServiceImpl(calculator, formatter); + // Initialiser la classe à tester + private final CalculatorService underTest = new CalculatorServiceImpl(calculator, formatter); - @Test - public void calculatorService_shouldCalculateASolution_whenGivenACalculationModel() { - // GIVEN - final CalculationModel calculation = new CalculationModel(CalculationType.ADDITION, - 100, 101); - // WHEN - final CalculationModel result = underTest.calculate(calculation); + @Test + void calculatorService_shouldCalculateASolution_whenGivenACalculationModel() { + // GIVEN + final CalculationModel calculation = new CalculationModel(CalculationType.ADDITION, + 100, 101); + // WHEN + final CalculationModel result = underTest.calculate(calculation); - // THEN - assertThat(result.getSolution()).isEqualTo(201); - } + // THEN + assertThat(result.getSolution()).isEqualTo(201); + } } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java index 8c18448..a41fbca 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java @@ -9,133 +9,131 @@ import static org.mockito.Mockito.when; import java.util.Random; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - import tech.zerofiltre.testing.calcul.domain.Calculator; import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; import tech.zerofiltre.testing.calcul.domain.model.CalculationType; @ExtendWith(MockitoExtension.class) -public class CalculatorServiceTest { - - @Mock - Calculator calculator; - - @Mock - SolutionFormatter solutionFormatter; - - CalculatorService classUnderTest; - - @BeforeEach - public void init() { - classUnderTest = new CalculatorServiceImpl(calculator, solutionFormatter); - } - - @Test - public void calculate_shouldUseCalculator_forAddition() { - // GIVEN - when(calculator.add(1, 2)).thenReturn(3); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, 1, 2)).getSolution(); - - // THEN - verify(calculator).add(1, 2); - assertThat(result).isEqualTo(3); - } - - @Test - public void calculate_shouldUseCalculator_forSubstraction() { - // GIVEN - when(calculator.sub(3, 2)).thenReturn(1); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.SUBTRACTION, 3, 2)) - .getSolution(); - - // THEN - verify(calculator).sub(3, 2); - assertThat(result).isEqualTo(1); - } - - @Test - public void calculate_shouldUseCalculator_forMultiplication() { - // GIVEN - when(calculator.multiply(-3, 2)).thenReturn(-6); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.MULTIPLICATION, -3, 2)) - .getSolution(); - - // THEN - verify(calculator).multiply(-3, 2); - assertThat(result).isEqualTo(-6); - } - - @Test - public void calculate_shouldUseCalculator_forDivision() { - // GIVEN - when(calculator.divide(6, 3)).thenReturn(2); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.DIVISION, 6, 3)) - .getSolution(); - - // THEN - verify(calculator).divide(6, 3); - assertThat(result).isEqualTo(2); - } - - @Test - public void calculate_shouldUseCalculator_forAnyAddition() { - // GIVEN - final Random r = new Random(); - when(calculator.add(any(Integer.class), any(Integer.class))).thenReturn(3); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, r.nextInt(), r.nextInt())).getSolution(); - - // THEN - verify(calculator, times(1)).add(any(Integer.class), any(Integer.class)); - verify(calculator, never()).sub(any(Integer.class), any(Integer.class)); - assertThat(result).isEqualTo(3); - } - - @Test - public void calculate_shouldThrowIllegalArgumentAxception_forADivisionBy0() { - // GIVEN - when(calculator.divide(1, 0)).thenThrow(new ArithmeticException()); - - // WHEN - assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate( - new CalculationModel(CalculationType.DIVISION, 1, 0))); - - // THEN - verify(calculator, times(1)).divide(1, 0); - } - - @Test - public void calculate_shouldFormatSolution_forAnAddition() { - // GIVEN - when(calculator.add(10000, 3000)).thenReturn(13000); - when(solutionFormatter.format(13000)).thenReturn("13 000"); - - // WHEN - final String formattedResult = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, 10000, 3000)).getFormattedSolution(); - - // THEN - assertThat(formattedResult).isEqualTo("13 000"); - } +class CalculatorServiceTest { + + @Mock + Calculator calculator; + + @Mock + SolutionFormatter solutionFormatter; + + CalculatorService classUnderTest; + + @BeforeEach + void init() { + classUnderTest = new CalculatorServiceImpl(calculator, solutionFormatter); + } + + @Test + void calculate_shouldUseCalculator_forAddition() { + // GIVEN + when(calculator.add(1, 2)).thenReturn(3); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, 1, 2)).getSolution(); + + // THEN + verify(calculator).add(1, 2); + assertThat(result).isEqualTo(3); + } + + @Test + void calculate_shouldUseCalculator_forSubstraction() { + // GIVEN + when(calculator.sub(3, 2)).thenReturn(1); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.SUBTRACTION, 3, 2)) + .getSolution(); + + // THEN + verify(calculator).sub(3, 2); + assertThat(result).isEqualTo(1); + } + + @Test + void calculate_shouldUseCalculator_forMultiplication() { + // GIVEN + when(calculator.multiply(-3, 2)).thenReturn(-6); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.MULTIPLICATION, -3, 2)) + .getSolution(); + + // THEN + verify(calculator).multiply(-3, 2); + assertThat(result).isEqualTo(-6); + } + + @Test + void calculate_shouldUseCalculator_forDivision() { + // GIVEN + when(calculator.divide(6, 3)).thenReturn(2); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.DIVISION, 6, 3)) + .getSolution(); + + // THEN + verify(calculator).divide(6, 3); + assertThat(result).isEqualTo(2); + } + + @Test + void calculate_shouldUseCalculator_forAnyAddition() { + // GIVEN + final Random r = new Random(); + when(calculator.add(any(Integer.class), any(Integer.class))).thenReturn(3); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, r.nextInt(), r.nextInt())).getSolution(); + + // THEN + verify(calculator, times(1)).add(any(Integer.class), any(Integer.class)); + verify(calculator, never()).sub(any(Integer.class), any(Integer.class)); + assertThat(result).isEqualTo(3); + } + + @Test + void calculate_shouldThrowIllegalArgumentAxception_forADivisionBy0() { + // GIVEN + when(calculator.divide(1, 0)).thenThrow(new ArithmeticException()); + + // WHEN + assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate( + new CalculationModel(CalculationType.DIVISION, 1, 0))); + + // THEN + verify(calculator, times(1)).divide(1, 0); + } + + @Test + void calculate_shouldFormatSolution_forAnAddition() { + // GIVEN + when(calculator.add(10000, 3000)).thenReturn(13000); + when(solutionFormatter.format(13000)).thenReturn("13 000"); + + // WHEN + final String formattedResult = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, 10000, 3000)).getFormattedSolution(); + + // THEN + assertThat(formattedResult).isEqualTo("13 000"); + } } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java index 15f0006..3e3ab4a 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java @@ -5,25 +5,25 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class SolutionFormatterTest { +class SolutionFormatterTest { - private SolutionFormatter solutionFormatter; + private SolutionFormatter solutionFormatter; - @BeforeEach - public void initFormatter() { - solutionFormatter = new SolutionFormatterImpl(); - } + @BeforeEach + void initFormatter() { + solutionFormatter = new SolutionFormatterImpl(); + } - @Test - public void format_shouldFormatAnyBigNumber() { - // GIVEN - final int number = 1234567890; + @Test + void format_shouldFormatAnyBigNumber() { + // GIVEN + final int number = 1234567890; - // WHEN - final String result = solutionFormatter.format(number); + // WHEN + final String result = solutionFormatter.format(number); - // THEN - assertThat(result).isEqualTo("1 234 567 890"); - } + // THEN + assertThat(result).isEqualTo("1 234 567 890"); + } } From 4ff35cb73ac3b26368ed2bca4088f7125df6bf72 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 21 Aug 2021 00:05:32 +0200 Subject: [PATCH 04/18] Configure Jacoco --- pom.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pom.xml b/pom.xml index 6aa21e1..cc8ec87 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,26 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + + prepare-agent + + + + + report + test + + report + + + + \ No newline at end of file From 641139bb09c7f63aaaec1e158d49be9d0d357f2a Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 21 Aug 2021 00:22:33 +0200 Subject: [PATCH 05/18] Coverage ratio set up --- .../testing/calcul/domain/DoubleCalculatorTest.java | 2 +- .../testing/calcul/e2e/MultiplicationJourneyE2ETest.java | 7 +++---- .../testing/calcul/service/CalculatorServiceTest.java | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java index 4ea6adf..a86975f 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java @@ -13,7 +13,7 @@ void initCalculator() { } @Test - @Disabled("Test ambigu et hors limite du type double") + @Disabled("Test ambigue et hors limite du type double") void subTwoDoubleNumbers_shouldReturnsTheCorrectAnswer() { // GIVEN diff --git a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java index aff1351..73d7765 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java @@ -10,7 +10,6 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; @@ -19,7 +18,7 @@ import org.springframework.boot.web.server.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public class MultiplicationJourneyE2ETest { +class MultiplicationJourneyE2ETest { @LocalServerPort private int port; @@ -47,7 +46,7 @@ void quitWebDriver() { } @Test - void multiplyTwoBySixteenMustReturn32(){ + void multiplyTwoBySixteenMustReturn32() { //GIVEN webDriver.get(baseUrl); @@ -63,7 +62,7 @@ void multiplyTwoBySixteenMustReturn32(){ submitButton.click(); //THEN - WebDriverWait waiter = new WebDriverWait(webDriver,5); + WebDriverWait waiter = new WebDriverWait(webDriver, 5); WebElement solutionElement = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("solution"))); String solution = solutionElement.getText(); assertThat(solution).isEqualTo("32"); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java index a41fbca..11334d6 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java @@ -115,8 +115,8 @@ void calculate_shouldThrowIllegalArgumentAxception_forADivisionBy0() { when(calculator.divide(1, 0)).thenThrow(new ArithmeticException()); // WHEN - assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate( - new CalculationModel(CalculationType.DIVISION, 1, 0))); + CalculationModel calculationModel = new CalculationModel(CalculationType.DIVISION, 1, 0); + assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate(calculationModel)); // THEN verify(calculator, times(1)).divide(1, 0); From b6023de38a188f42b999bcfbb75622359ad26652 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Wed, 25 Aug 2021 04:52:28 +0200 Subject: [PATCH 06/18] Add profiles configurations --- Dockerfile | 13 +++++++++++++ entrypoint.sh | 4 ++++ src/main/resources/application-dev.yaml | 2 ++ src/main/resources/application-prod.yaml | 2 ++ src/main/resources/application-uat.yaml | 2 ++ 5 files changed, 23 insertions(+) create mode 100644 Dockerfile create mode 100644 entrypoint.sh create mode 100644 src/main/resources/application-dev.yaml create mode 100644 src/main/resources/application-prod.yaml create mode 100644 src/main/resources/application-uat.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d92b1a3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM adoptopenjdk/openjdk11:alpine-jre + +ARG JAR_FILE=target/calculator.jar + +WORKDIR /opt/app + +COPY ${JAR_FILE} calculator.jar + +COPY entrypoint.sh entrypoint.sh + +RUN chmod 755 entrypoint.sh + +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..4d68d33 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +echo "The app is starting ..." +exec java -jar -Dspring.profiles.active=${SPRING_ACTIVE_PROFILES} "calculator.jar" \ No newline at end of file diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..47fbb02 --- /dev/null +++ b/src/main/resources/application-dev.yaml @@ -0,0 +1,2 @@ +server: + port: 8080 \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..3621202 --- /dev/null +++ b/src/main/resources/application-prod.yaml @@ -0,0 +1,2 @@ +server: + port: 9001 \ No newline at end of file diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml new file mode 100644 index 0000000..e346b3d --- /dev/null +++ b/src/main/resources/application-uat.yaml @@ -0,0 +1,2 @@ +server: + port: 9000 \ No newline at end of file From 8bf43ecb046ee0ae072ddad243c38bd1cb35b5c9 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Wed, 25 Aug 2021 22:59:36 +0200 Subject: [PATCH 07/18] Add Jenkinsfile --- Jenkinsfile | 103 ++++++++ pom.xml | 247 +++++++++--------- src/main/resources/application-dev.yaml | 2 +- src/main/resources/application-prod.yaml | 2 +- src/main/resources/application-uat.yaml | 2 +- ...est.java => MultiplicationJourneyE2E.java} | 2 +- 6 files changed, 231 insertions(+), 127 deletions(-) create mode 100644 Jenkinsfile rename src/test/java/tech/zerofiltre/testing/calcul/e2e/{MultiplicationJourneyE2ETest.java => MultiplicationJourneyE2E.java} (98%) diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..97abb6f --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,103 @@ +def CONTAINER_NAME = "calculator" +def ENV_NAME = ${ getEnvName(env.BRANCH_NAME) } +def CONTAINER_TAG = ${ getTag(env.BUILD_NUMBER, env.BRANCH_NAME) } +def HTTP_PORT = ${getHTTPPort(env.BRANCH_NAME) } + + +node { + + stage('Initialize') { + def dockerHome = tool 'DockerLatest' + def mavenHome = tool 'MavenLatest' + env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}" + } + + stage('Checkout') { + checkout scm + } + + stage('Build with test') { + sh "mvn clean install" + } + + stage('Sonarqube Analysis') { + withSonarQubeEnv('SonarQubeLocalServer') { + sh " mvn sonar:sonar -Dintegration-tests.skip=true -Dmaven.test.failure.ignore=true" + } + timeout(time: 1, unit: 'MINUTES') { + def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } + } + } + + stage("Image Prune") { + imagePrune(CONTAINER_NAME) + } + + stage('Image Build') { + imageBuild(CONTAINER_NAME, CONTAINER_TAG) + } + + stage('Push to Docker Registry') { + withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { + pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD) + } + } + + stage('Run App') { + withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { + runApp(CONTAINER_NAME, CONTAINER_TAG, USERNAME, HTTP_PORT, ENV_NAME) + + } + } + +} + +def imagePrune(containerName) { + try { + sh "docker image prune -f" + sh "docker stop $containerName" + } catch (ignored) { + } +} + +def imageBuild(containerName, tag) { + sh "docker build -t $containerName:$tag -t $containerName --pull --no-cache ." + echo "Image build complete" +} + +def pushToImage(containerName, tag, dockerUser, dockerPassword) { + sh "docker login -u $dockerUser -p $dockerPassword" + sh "docker tag $containerName:$tag $dockerUser/$containerName:$tag" + sh "docker push $dockerUser/$containerName:$tag" + echo "Image push complete" +} + +def runApp(containerName, tag, dockerHubUser, httpPort,envName) { + sh "docker pull $dockerHubUser/$containerName" + sh "docker run --rm --env --env SPRING_ACTIVE_PROFILES=$envName -d -p $httpPort:$httpPort --name $containerName $dockerHubUser/$containerName:$tag" + echo "Application started on port: ${httpPort} (http)" +} + +String getEnvName(String branchName) { + if (branchName == 'main') { + return 'prod' + } + return (branchName == 'develop') ? 'uat' : 'dev' +} + +String getHTTPPort(String branchName) { + if (branchName == 'main') { + return '9003' + } + return (branchName == 'develop') ? '9002' : '9001' +} + +String getTag(String buildNumber, String branchName) { + if (branchName == 'main') { + return buildNumber + '-unstable' + } + return buildNumber + '-stable' +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index cc8ec87..1b16bd0 100644 --- a/pom.xml +++ b/pom.xml @@ -1,127 +1,128 @@ - 4.0.0 - com.openclassrooms.testing - calculator - 0.0.1-SNAPSHOT - - 5.5.2 - UTF-8 - 11 - ${maven.compiler.source} - 4.3.1 - 2.2.0.RELEASE - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + tech.zerofiltre.testing + calculator + 0.0.1-SNAPSHOT + + 5.5.2 + UTF-8 + 11 + ${maven.compiler.source} + 4.3.1 + 2.2.0.RELEASE + tech.zerofiltre.testing:calculator + - - org.springframework.boot - spring-boot-starter-parent - 2.2.0.RELEASE - + + org.springframework.boot + spring-boot-starter-parent + 2.2.0.RELEASE + - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-devtools - runtime - - - org.webjars - bootstrap - ${bootstrap.version} - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-junit-jupiter - test - - - org.assertj - assertj-core - test - - - org.apache.logging.log4j - log4j-core - - - javax.inject - javax.inject - 1 - - - org.seleniumhq.selenium - selenium-java - test - - - io.github.bonigarcia - webdrivermanager - 3.7.1 - - - - calculator - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.2 - - - - prepare-agent - - - - - report - test - - report - - - - - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.webjars + bootstrap + ${bootstrap.version} + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter + test + + + org.mockito + mockito-junit-jupiter + test + + + org.assertj + assertj-core + test + + + org.apache.logging.log4j + log4j-core + + + javax.inject + javax.inject + 1 + + + org.seleniumhq.selenium + selenium-java + test + + + io.github.bonigarcia + webdrivermanager + 3.7.1 + + + + calculator + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + + prepare-agent + + + + + report + test + + report + + + + + + \ No newline at end of file diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index 47fbb02..3621202 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -1,2 +1,2 @@ server: - port: 8080 \ No newline at end of file + port: 9001 \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 3621202..9beecae 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,2 +1,2 @@ server: - port: 9001 \ No newline at end of file + port: 9003 \ No newline at end of file diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml index e346b3d..5af7893 100644 --- a/src/main/resources/application-uat.yaml +++ b/src/main/resources/application-uat.yaml @@ -1,2 +1,2 @@ server: - port: 9000 \ No newline at end of file + port: 9002 \ No newline at end of file diff --git a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2E.java similarity index 98% rename from src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java rename to src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2E.java index 73d7765..24eac6f 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2E.java @@ -18,7 +18,7 @@ import org.springframework.boot.web.server.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class MultiplicationJourneyE2ETest { +class MultiplicationJourneyE2E { @LocalServerPort private int port; From 8e32b213d73f7c9b9ebe74c41a1c6ccc81b50125 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Thu, 26 Aug 2021 22:40:33 +0200 Subject: [PATCH 08/18] Send email after pipeline --- Jenkinsfile | 92 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 97abb6f..57d3199 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,56 +1,63 @@ def CONTAINER_NAME = "calculator" -def ENV_NAME = ${ getEnvName(env.BRANCH_NAME) } -def CONTAINER_TAG = ${ getTag(env.BUILD_NUMBER, env.BRANCH_NAME) } -def HTTP_PORT = ${getHTTPPort(env.BRANCH_NAME) } +def ENV_NAME = getEnvName(env.BRANCH_NAME) +def CONTAINER_TAG = getTag(env.BUILD_NUMBER, env.BRANCH_NAME) +def HTTP_PORT = getHTTPPort(env.BRANCH_NAME) +def EMAIL_RECIPIENTS = "philippe.guemkamsimo@gmail.com" node { + try { + stage('Initialize') { + def dockerHome = tool 'DockerLatest' + def mavenHome = tool 'MavenLatest' + env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}" + } - stage('Initialize') { - def dockerHome = tool 'DockerLatest' - def mavenHome = tool 'MavenLatest' - env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}" - } + stage('Checkout') { + checkout scm + } - stage('Checkout') { - checkout scm - } + stage('Build with test') { - stage('Build with test') { - sh "mvn clean install" - } - - stage('Sonarqube Analysis') { - withSonarQubeEnv('SonarQubeLocalServer') { - sh " mvn sonar:sonar -Dintegration-tests.skip=true -Dmaven.test.failure.ignore=true" + sh "mvn clean install" } - timeout(time: 1, unit: 'MINUTES') { - def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv - if (qg.status != 'OK') { - error "Pipeline aborted due to quality gate failure: ${qg.status}" + + stage('Sonarqube Analysis') { + withSonarQubeEnv('SonarQubeLocalServer') { + sh " mvn sonar:sonar -Dintegration-tests.skip=true -Dmaven.test.failure.ignore=true" + } + timeout(time: 1, unit: 'MINUTES') { + def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } } } - } - stage("Image Prune") { - imagePrune(CONTAINER_NAME) - } + stage("Image Prune") { + imagePrune(CONTAINER_NAME) + } - stage('Image Build') { - imageBuild(CONTAINER_NAME, CONTAINER_TAG) - } + stage('Image Build') { + imageBuild(CONTAINER_NAME, CONTAINER_TAG) + } - stage('Push to Docker Registry') { - withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { - pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD) + stage('Push to Docker Registry') { + withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { + pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD) + } } - } - stage('Run App') { - withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { - runApp(CONTAINER_NAME, CONTAINER_TAG, USERNAME, HTTP_PORT, ENV_NAME) + stage('Run App') { + withCredentials([usernamePassword(credentialsId: 'DockerhubCredentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { + runApp(CONTAINER_NAME, CONTAINER_TAG, USERNAME, HTTP_PORT, ENV_NAME) + } } + + } finally { + deleteDir() + sendEmail(EMAIL_RECIPIENTS); } } @@ -75,12 +82,19 @@ def pushToImage(containerName, tag, dockerUser, dockerPassword) { echo "Image push complete" } -def runApp(containerName, tag, dockerHubUser, httpPort,envName) { +def runApp(containerName, tag, dockerHubUser, httpPort, envName) { sh "docker pull $dockerHubUser/$containerName" - sh "docker run --rm --env --env SPRING_ACTIVE_PROFILES=$envName -d -p $httpPort:$httpPort --name $containerName $dockerHubUser/$containerName:$tag" + sh "docker run --rm --env SPRING_ACTIVE_PROFILES=$envName -d -p $httpPort:$httpPort --name $containerName $dockerHubUser/$containerName:$tag" echo "Application started on port: ${httpPort} (http)" } +def sendEmail(recipients) { + mail( + to: recipients, + subject: "Build ${env.BUILD_NUMBER} - ${currentBuild.currentResult} - (${currentBuild.fullDisplayName})", + body: "Check console output at: ${env.BUILD_URL}/console" + "\n") +} + String getEnvName(String branchName) { if (branchName == 'main') { return 'prod' @@ -100,4 +114,4 @@ String getTag(String buildNumber, String branchName) { return buildNumber + '-unstable' } return buildNumber + '-stable' -} \ No newline at end of file +} From 4a15dd8efd29e057de4f0ac0d8c7e83908296330 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 28 Aug 2021 20:51:41 +0200 Subject: [PATCH 09/18] Deploy ready branch on port 9002,main on 9001 and others on 9003 --- Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 57d3199..27e5b2f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -99,14 +99,14 @@ String getEnvName(String branchName) { if (branchName == 'main') { return 'prod' } - return (branchName == 'develop') ? 'uat' : 'dev' + return (branchName == 'ready') ? 'uat' : 'dev' } String getHTTPPort(String branchName) { if (branchName == 'main') { - return '9003' + return '9001' } - return (branchName == 'develop') ? '9002' : '9001' + return (branchName == 'ready') ? '9002' : '9003' } String getTag(String buildNumber, String branchName) { From 4a7dd1d562446b150b49a390fbc7629be1c3c13e Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 28 Aug 2021 21:09:44 +0200 Subject: [PATCH 10/18] Deploy release-* and hotfix-* branches on uat env --- Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 27e5b2f..efa0f89 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -98,8 +98,10 @@ def sendEmail(recipients) { String getEnvName(String branchName) { if (branchName == 'main') { return 'prod' + } else if (branchName.startsWith("release-") || branchName.startsWith("hotfix-") || branchName == 'ready') { + return 'uat' } - return (branchName == 'ready') ? 'uat' : 'dev' + return 'dev' } String getHTTPPort(String branchName) { From 77265352a4abcd6b182db25316d03e267065b85a Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 28 Aug 2021 21:22:27 +0200 Subject: [PATCH 11/18] Deploy release,hotfix and ready branch on port 9002 --- Jenkinsfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index efa0f89..182e235 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -107,8 +107,11 @@ String getEnvName(String branchName) { String getHTTPPort(String branchName) { if (branchName == 'main') { return '9001' + + } else if (branchName.startsWith("release-") || branchName.startsWith("hotfix-") || branchName == 'ready') { + return '9002' } - return (branchName == 'ready') ? '9002' : '9003' + return '9003' } String getTag(String buildNumber, String branchName) { From 6d4439c7333f16854b85f25a6b3ec29bd797202d Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Sat, 28 Aug 2021 21:22:59 +0200 Subject: [PATCH 12/18] Deploy dev to 9003 and prod to 9001 --- src/main/resources/application-dev.yaml | 2 +- src/main/resources/application-prod.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index 3621202..9beecae 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -1,2 +1,2 @@ server: - port: 9001 \ No newline at end of file + port: 9003 \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 9beecae..3621202 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,2 +1,2 @@ server: - port: 9003 \ No newline at end of file + port: 9001 \ No newline at end of file From 730b24c330d5c78111d01c2a2378346c5c74a9c2 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Mon, 30 Aug 2021 22:24:52 +0200 Subject: [PATCH 13/18] Liquibase with Postgres not working --- derby.log | 0 pom.xml | 104 ++++++++++++++ .../testing/calcul/CalculatorApp.java | 7 +- .../calcul/domain/model/CalculationModel.java | 131 +++++++----------- .../CalculationModelRepository.java | 8 ++ src/main/resources/application-dev.yaml | 14 ++ src/main/resources/application-prod.yaml | 13 ++ src/main/resources/application-uat.yaml | 13 ++ src/main/resources/application.yaml | 18 +++ .../resources/db/changelog/changes/.gitkeep | 0 .../db/changelog/db.changelog-dev.yaml | 3 + .../db/changelog/db.changelog-master.yaml | 3 + .../db/changelog/db.changelog-prod.yaml | 3 + .../db/changelog/db.changelog-uat.yaml | 3 + src/main/resources/liquibase.properties | 12 ++ 15 files changed, 251 insertions(+), 81 deletions(-) create mode 100644 derby.log create mode 100644 src/main/java/tech/zerofiltre/testing/calcul/repository/CalculationModelRepository.java create mode 100644 src/main/resources/application.yaml create mode 100644 src/main/resources/db/changelog/changes/.gitkeep create mode 100644 src/main/resources/db/changelog/db.changelog-dev.yaml create mode 100644 src/main/resources/db/changelog/db.changelog-master.yaml create mode 100644 src/main/resources/db/changelog/db.changelog-prod.yaml create mode 100644 src/main/resources/db/changelog/db.changelog-uat.yaml create mode 100644 src/main/resources/liquibase.properties diff --git a/derby.log b/derby.log new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 1b16bd0..d9f47cd 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,14 @@ 4.3.1 2.2.0.RELEASE tech.zerofiltre.testing:calculator + + 5.4.24.Final + 4.2.0 + 4.2.0 + 4.1.1 + 2.0.1.Final + 3.27.0-GA + 2.4.0-b180830.0359 @@ -34,6 +42,10 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.springframework.boot + spring-boot-starter-data-jpa + org.springframework.boot spring-boot-devtools @@ -44,6 +56,12 @@ bootstrap ${bootstrap.version} + + org.liquibase + liquibase-core + ${liquibase-core.version} + + org.junit.jupiter junit-jupiter-api @@ -73,6 +91,12 @@ javax.inject 1 + + org.projectlombok + lombok + 1.18.20 + provided + org.seleniumhq.selenium selenium-java @@ -83,7 +107,41 @@ webdrivermanager 3.7.1 + + + org.postgresql + postgresql + + + + + + dev + + true + + + dev + + + + + test + + uat + + + + + prod + + prod + + + + + calculator @@ -123,6 +181,52 @@ + + org.liquibase + liquibase-maven-plugin + ${liquibase-maven-plugin.version} + + src/main/resources/liquibase.properties + src/main/resources/db/changelog/db.changelog-${activeProfile}.xml + src/main/resources/db/changelog/db.changelog-${activeProfile}.xml + + src/main/resources/db/changelog/changes/${activeProfile}/${maven.build.timestamp}_changelog.xml + + info + + + + org.liquibase + liquibase-core + ${liquibase-core.version} + + + org.liquibase.ext + liquibase-hibernate5 + ${liquibase-hibernate5.version} + + + org.springframework.boot + spring-boot-starter-data-jpa + ${springboot.version} + + + javax.validation + validation-api + ${validation-api.version} + + + org.javassist + javassist + ${javassist.version} + + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + + + \ No newline at end of file diff --git a/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java b/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java index 2dd9867..45bbae1 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java @@ -2,11 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; @SpringBootApplication public class CalculatorApp { - public static void main(String[] args) { - SpringApplication.run(CalculatorApp.class, args); - } + public static void main(String[] args) { + SpringApplication.run(CalculatorApp.class, args); + } } diff --git a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java index 0e6599a..3e30f55 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java @@ -1,86 +1,61 @@ package tech.zerofiltre.testing.calcul.domain.model; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import lombok.Data; +import lombok.NoArgsConstructor; + /** - * A model to represent a two argument integer calculation which needs to be - * performed. - * + * A model to represent a two argument integer calculation which needs to be performed. */ +@Data +@Entity +@NoArgsConstructor public class CalculationModel { - private static final String SEPARATOR = " "; - private Integer leftArgument; - private Integer rightArgument; - private CalculationType type; - private Integer solution; - private String formattedSolution; - - public CalculationModel(CalculationType calculationType, int leftArgument, int rightArgument) { - type = calculationType; - this.leftArgument = leftArgument; - this.rightArgument = rightArgument; - } - - /** - * Convenience Constructor used in test - */ - public CalculationModel(CalculationType calculationType, int leftArgument, int rightArgument, Integer solution) { - type = calculationType; - this.leftArgument = leftArgument; - this.rightArgument = rightArgument; - this.solution = solution; - } - - /** - * Builds a Calculation from a string such as 2 + 2 - * - * @param calculation in written form - * @return model representing the calculatoin - */ - public static CalculationModel fromText(String calculation) { - final String[] parts = calculation.split(SEPARATOR); - final int leftArgument = Integer.parseInt(parts[0]); - final int rightArgument = Integer.parseInt(parts[2]); - final CalculationType calculationType = CalculationType.fromSymbol(parts[1]); - - return new CalculationModel(calculationType, leftArgument, rightArgument); - } - - public Integer getLeftArgument() { - return leftArgument; - } - - public void setLeftArgument(Integer leftArgument) { - this.leftArgument = leftArgument; - } - - public Integer getRightArgument() { - return rightArgument; - } - - public void setRightArgument(Integer rightArgument) { - this.rightArgument = rightArgument; - } - - public CalculationType getType() { - return type; - } - - public void setType(CalculationType type) { - this.type = type; - } - - public Integer getSolution() { - return solution; - } - - public void setSolution(Integer solution) { - this.solution = solution; - } - public String getFormattedSolution() { - return formattedSolution; - } + private static final String SEPARATOR = " "; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private Integer leftArgument; + private Integer rightArgument; + private CalculationType type; + private Integer solution; + private String formattedSolution; + + public CalculationModel(CalculationType calculationType, int leftArgument, int rightArgument) { + type = calculationType; + this.leftArgument = leftArgument; + this.rightArgument = rightArgument; + } + + /** + * Convenience Constructor used in test + */ + public CalculationModel(CalculationType calculationType, int leftArgument, int rightArgument, Integer solution) { + type = calculationType; + this.leftArgument = leftArgument; + this.rightArgument = rightArgument; + this.solution = solution; + } + + /** + * Builds a Calculation from a string such as 2 + 2 + * + * @param calculation in written form + * @return model representing the calculatoin + */ + public static CalculationModel fromText(String calculation) { + final String[] parts = calculation.split(SEPARATOR); + final int leftArgument = Integer.parseInt(parts[0]); + final int rightArgument = Integer.parseInt(parts[2]); + final CalculationType calculationType = CalculationType.fromSymbol(parts[1]); + + return new CalculationModel(calculationType, leftArgument, rightArgument); + } - public void setFormattedSolution(String formattedSolution) { - this.formattedSolution = formattedSolution; - } } diff --git a/src/main/java/tech/zerofiltre/testing/calcul/repository/CalculationModelRepository.java b/src/main/java/tech/zerofiltre/testing/calcul/repository/CalculationModelRepository.java new file mode 100644 index 0000000..02a080b --- /dev/null +++ b/src/main/java/tech/zerofiltre/testing/calcul/repository/CalculationModelRepository.java @@ -0,0 +1,8 @@ +package tech.zerofiltre.testing.calcul.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; + +public interface CalculationModelRepository extends JpaRepository { + +} diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index 9beecae..e40bed4 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -1,2 +1,16 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5434/calculator + username: postgres + password: mysecretpassword + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: none + liquibase: + change-log: classpath:/db/changelog/db.changelog-dev.yaml + + server: port: 9003 \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 3621202..7070424 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,2 +1,15 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5436/calculator + username: postgres + password: mysecretpassword + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: none + liquibase: + change-log: classpath:/db/changelog/db.changelog-prod.yaml + server: port: 9001 \ No newline at end of file diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml index 5af7893..089e21d 100644 --- a/src/main/resources/application-uat.yaml +++ b/src/main/resources/application-uat.yaml @@ -1,2 +1,15 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5435/calculator + username: postgres + password: mysecretpassword + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: none + liquibase: + change-log: classpath:/db/changelog/db.changelog-uat.yaml + server: port: 9002 \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..2be1588 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,18 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5433/calculator + username: postgres + password: mysecretpassword + driver-class-name: org.postgresql.Driver + + jpa: + databse-platform: org.hibernate.dialect.PostgreSQL9Dialect + properties: + hibernate: + temp: + use_jdbc_metadata_defaults: false + hibernate: + ddl-auto: update + +server: + port: 8999 \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/.gitkeep b/src/main/resources/db/changelog/changes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/db/changelog/db.changelog-dev.yaml b/src/main/resources/db/changelog/db.changelog-dev.yaml new file mode 100644 index 0000000..0310fd0 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-dev.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - includeAll: + path: db/changelog/changes/dev \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml new file mode 100644 index 0000000..8ad4178 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - includeAll: + path: db/changelog/changes \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-prod.yaml b/src/main/resources/db/changelog/db.changelog-prod.yaml new file mode 100644 index 0000000..108e535 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-prod.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - includeAll: + path: db/changelog/changes/prod \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-uat.yaml b/src/main/resources/db/changelog/db.changelog-uat.yaml new file mode 100644 index 0000000..dd13535 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-uat.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - includeAll: + path: db/changelog/changes/uat \ No newline at end of file diff --git a/src/main/resources/liquibase.properties b/src/main/resources/liquibase.properties new file mode 100644 index 0000000..47b108a --- /dev/null +++ b/src/main/resources/liquibase.properties @@ -0,0 +1,12 @@ + +#### Database properties +url=${liquibase.url} +username=${liquibase.username} +password=${liquibase.password} +#driver=org.hibernate.dialect.PostgreSQL9Dialect + +#### Reference database properties +referenceUrl=${liquibase.referenceUrl} +referenceDriver=org.hibernate.dialect.PostgreSQL9Dialect +referenceUsername=${liquibase.referenceUsername} +referencePassword=${liquibase.referencePassword} \ No newline at end of file From 38f8769df1473d16ea203c25fd56017488a4e25b Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Tue, 31 Aug 2021 12:43:13 +0200 Subject: [PATCH 14/18] liquibase with mysql --- pom.xml | 24 ++++-- .../testing/calcul/CalculatorApp.java | 1 - .../controller/CalculatorController.java | 56 +++++++------ src/main/resources/application-dev.yaml | 7 +- src/main/resources/application-prod.yaml | 7 +- src/main/resources/application-uat.yaml | 7 +- src/main/resources/application.yaml | 12 +-- .../db/changelog/db.changelog-dev.yaml | 2 +- .../db/changelog/db.changelog-prod.yaml | 2 +- .../db/changelog/db.changelog-uat.yaml | 2 +- src/main/resources/liquibase.properties | 8 +- .../controller/CalculatorControllerSIT.java | 84 +++++++++++-------- .../controller/CalculatorControllerTest.java | 60 +++++++++++++ .../CalculationModelRepositorySIT.java | 24 ++++++ 14 files changed, 203 insertions(+), 93 deletions(-) create mode 100644 src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerTest.java create mode 100644 src/test/java/tech/zerofiltre/testing/calcul/repository/CalculationModelRepositorySIT.java diff --git a/pom.xml b/pom.xml index d9f47cd..ec2b6ba 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,10 @@ 4.3.1 2.2.0.RELEASE tech.zerofiltre.testing:calculator + + **/domain/**/*.java, + src/test/java/*.java + 5.4.24.Final 4.2.0 @@ -21,6 +25,8 @@ 2.0.1.Final 3.27.0-GA 2.4.0-b180830.0359 + yyyy-MM-dd_HH-mm + @@ -51,6 +57,12 @@ spring-boot-devtools runtime + + + com.h2database + h2 + runtime + org.webjars bootstrap @@ -107,12 +119,10 @@ webdrivermanager 3.7.1 - - org.postgresql - postgresql + mysql + mysql-connector-java - @@ -187,10 +197,10 @@ ${liquibase-maven-plugin.version} src/main/resources/liquibase.properties - src/main/resources/db/changelog/db.changelog-${activeProfile}.xml - src/main/resources/db/changelog/db.changelog-${activeProfile}.xml + src/main/resources/db/changelog/db.changelog-${activeProfile}.yaml + src/main/resources/db/changelog/db.changelog-${activeProfile}.yaml - src/main/resources/db/changelog/changes/${activeProfile}/${maven.build.timestamp}_changelog.xml + src/main/resources/db/changelog/changes/${activeProfile}/${maven.build.timestamp}_changelog.yaml info diff --git a/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java b/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java index 45bbae1..fa36566 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/CalculatorApp.java @@ -2,7 +2,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; @SpringBootApplication public class CalculatorApp { diff --git a/src/main/java/tech/zerofiltre/testing/calcul/controller/CalculatorController.java b/src/main/java/tech/zerofiltre/testing/calcul/controller/CalculatorController.java index f89c344..36f5c3e 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/controller/CalculatorController.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/controller/CalculatorController.java @@ -2,48 +2,56 @@ import javax.inject.Inject; import javax.validation.Valid; - import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; - import tech.zerofiltre.testing.calcul.domain.model.Calculation; import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; import tech.zerofiltre.testing.calcul.domain.model.CalculationType; +import tech.zerofiltre.testing.calcul.repository.CalculationModelRepository; import tech.zerofiltre.testing.calcul.service.CalculatorService; @Controller public class CalculatorController { - public static final String CALCULATOR_TEMPLATE = "calculator"; + public static final String CALCULATOR_TEMPLATE = "calculator"; + + CalculatorService calculatorService; + + CalculationModelRepository calculationModelRepository; + + public CalculatorController(CalculatorService calculatorService, + CalculationModelRepository calculationModelRepository) { + this.calculatorService = calculatorService; + this.calculationModelRepository = calculationModelRepository; + } - @Inject - CalculatorService calculatorService; + @GetMapping("/") + public String index(Calculation calculation) { + return "redirect:/calculator"; + } - @GetMapping("/") - public String index(Calculation calculation) { - return "redirect:/calculator"; - } + @GetMapping("/calculator") + public String root(Calculation calculation) { + return CALCULATOR_TEMPLATE; // cf. resources/templates/calculator.html + } - @GetMapping("/calculator") - public String root(Calculation calculation) { - return CALCULATOR_TEMPLATE; // cf. resources/templates/calculator.html - } + @PostMapping("/calculator") + public String calculate(@Valid Calculation calculation, BindingResult bindingResult, Model model) { - @PostMapping("/calculator") - public String calculate(@Valid Calculation calculation, BindingResult bindingResult, Model model) { + final CalculationType type = CalculationType.valueOf(calculation.getCalculationType()); + final CalculationModel calculationModel = new CalculationModel( + type, + calculation.getLeftArgument(), + calculation.getRightArgument()); - final CalculationType type = CalculationType.valueOf(calculation.getCalculationType()); - final CalculationModel calculationModel = new CalculationModel( - type, - calculation.getLeftArgument(), - calculation.getRightArgument()); + final CalculationModel response = calculatorService.calculate(calculationModel); - final CalculationModel response = calculatorService.calculate(calculationModel); + calculationModelRepository.save(response); - model.addAttribute("response", response); - return CALCULATOR_TEMPLATE; // cf. resources/templates/calculator.html - } + model.addAttribute("response", response); + return CALCULATOR_TEMPLATE; // cf. resources/templates/calculator.html + } } diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index e40bed4..84c0ebf 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -1,9 +1,8 @@ spring: datasource: - url: jdbc:postgresql://localhost:5434/calculator - username: postgres - password: mysecretpassword - driver-class-name: org.postgresql.Driver + url: jdbc:mysql://localhost:3307/calculator?serverTimezone=UTC + username: root + password: my-secret-pw jpa: hibernate: diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 7070424..dcdd938 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,9 +1,8 @@ spring: datasource: - url: jdbc:postgresql://localhost:5436/calculator - username: postgres - password: mysecretpassword - driver-class-name: org.postgresql.Driver + url: jdbc:mysql://localhost:3309/calculator?serverTimezone=UTC + username: root + password: my-secret-pw jpa: hibernate: diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml index 089e21d..86283e8 100644 --- a/src/main/resources/application-uat.yaml +++ b/src/main/resources/application-uat.yaml @@ -1,9 +1,8 @@ spring: datasource: - url: jdbc:postgresql://localhost:5435/calculator - username: postgres - password: mysecretpassword - driver-class-name: org.postgresql.Driver + url: jdbc:mysql://localhost:3308/calculator?serverTimezone=UTC + username: root + password: my-secret-pw jpa: hibernate: diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 2be1588..ad5a9c1 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,16 +1,10 @@ spring: datasource: - url: jdbc:postgresql://localhost:5433/calculator - username: postgres - password: mysecretpassword - driver-class-name: org.postgresql.Driver + url: jdbc:mysql://localhost:3306/calculator?serverTimezone=UTC + username: root + password: my-secret-pw jpa: - databse-platform: org.hibernate.dialect.PostgreSQL9Dialect - properties: - hibernate: - temp: - use_jdbc_metadata_defaults: false hibernate: ddl-auto: update diff --git a/src/main/resources/db/changelog/db.changelog-dev.yaml b/src/main/resources/db/changelog/db.changelog-dev.yaml index 0310fd0..c29655e 100644 --- a/src/main/resources/db/changelog/db.changelog-dev.yaml +++ b/src/main/resources/db/changelog/db.changelog-dev.yaml @@ -1,3 +1,3 @@ databaseChangeLog: - includeAll: - path: db/changelog/changes/dev \ No newline at end of file + path: src/main/resources/db/changelog/changes/dev \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-prod.yaml b/src/main/resources/db/changelog/db.changelog-prod.yaml index 108e535..6535f89 100644 --- a/src/main/resources/db/changelog/db.changelog-prod.yaml +++ b/src/main/resources/db/changelog/db.changelog-prod.yaml @@ -1,3 +1,3 @@ databaseChangeLog: - includeAll: - path: db/changelog/changes/prod \ No newline at end of file + path: src/main/resources/db/changelog/changes/prod \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-uat.yaml b/src/main/resources/db/changelog/db.changelog-uat.yaml index dd13535..768f9c9 100644 --- a/src/main/resources/db/changelog/db.changelog-uat.yaml +++ b/src/main/resources/db/changelog/db.changelog-uat.yaml @@ -1,3 +1,3 @@ databaseChangeLog: - includeAll: - path: db/changelog/changes/uat \ No newline at end of file + path: src/main/resources/db/changelog/changes/uat \ No newline at end of file diff --git a/src/main/resources/liquibase.properties b/src/main/resources/liquibase.properties index 47b108a..a12db58 100644 --- a/src/main/resources/liquibase.properties +++ b/src/main/resources/liquibase.properties @@ -3,10 +3,12 @@ url=${liquibase.url} username=${liquibase.username} password=${liquibase.password} -#driver=org.hibernate.dialect.PostgreSQL9Dialect +driver=com.mysql.cj.jdbc.Driver #### Reference database properties referenceUrl=${liquibase.referenceUrl} -referenceDriver=org.hibernate.dialect.PostgreSQL9Dialect +referenceDriver=com.mysql.cj.jdbc.Driver referenceUsername=${liquibase.referenceUsername} -referencePassword=${liquibase.referencePassword} \ No newline at end of file +referencePassword=${liquibase.referencePassword} + +diffTypes=tables, views, columns, indexes, foreignkeys, primarykeys, uniqueconstraints, data \ No newline at end of file diff --git a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java index b81b853..a9a26ca 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java @@ -1,57 +1,73 @@ package tech.zerofiltre.testing.calcul.controller; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import javax.inject.Inject; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; - +import org.springframework.test.web.servlet.setup.MockMvcBuilders; import tech.zerofiltre.testing.calcul.domain.Calculator; +import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; +import tech.zerofiltre.testing.calcul.repository.CalculationModelRepository; import tech.zerofiltre.testing.calcul.service.CalculatorService; +import tech.zerofiltre.testing.calcul.service.CalculatorServiceImpl; import tech.zerofiltre.testing.calcul.service.SolutionFormatter; -@WebMvcTest(controllers = { CalculatorController.class, CalculatorService.class }) +@Disabled @ExtendWith(SpringExtension.class) class CalculatorControllerSIT { - @Inject - private MockMvc mockMvc; - - @MockBean - private SolutionFormatter solutionFormatter; - - @MockBean - private Calculator calculator; - - @Test - void givenACalculatorApp_whenRequestToAdd_thenSolutionIsShown() throws Exception { - // GIVEN - when(calculator.add(2, 3)).thenReturn(5); - - // WHEN - final MvcResult result = mockMvc.perform( - MockMvcRequestBuilders.post("/calculator") - .param("leftArgument", "2") - .param("rightArgument", "3") - .param("calculationType", "ADDITION")) - .andExpect(MockMvcResultMatchers.status().is2xxSuccessful()) - .andReturn(); - - // THEN - assertThat(result.getResponse().getContentAsString()) - .contains("id=\"solution\"") - .contains(">55 Date: Tue, 31 Aug 2021 13:30:13 +0200 Subject: [PATCH 15/18] Disable liquibase at startup --- src/main/resources/application-dev.yaml | 3 ++- src/main/resources/application-prod.yaml | 3 ++- src/main/resources/application-uat.yaml | 3 ++- src/main/resources/application.yaml | 4 ++++ src/main/resources/db/changelog/db.changelog-master.yaml | 3 --- 5 files changed, 10 insertions(+), 6 deletions(-) delete mode 100644 src/main/resources/db/changelog/db.changelog-master.yaml diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index 84c0ebf..200ed7a 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -8,7 +8,8 @@ spring: hibernate: ddl-auto: none liquibase: - change-log: classpath:/db/changelog/db.changelog-dev.yaml + #disable liquibase at start-up + enabled: false server: diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index dcdd938..a4ee265 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -8,7 +8,8 @@ spring: hibernate: ddl-auto: none liquibase: - change-log: classpath:/db/changelog/db.changelog-prod.yaml + #disable liquibase at start-up + enabled: false server: port: 9001 \ No newline at end of file diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml index 86283e8..86edf80 100644 --- a/src/main/resources/application-uat.yaml +++ b/src/main/resources/application-uat.yaml @@ -8,7 +8,8 @@ spring: hibernate: ddl-auto: none liquibase: - change-log: classpath:/db/changelog/db.changelog-uat.yaml + #disable liquibase at start-up + enabled: false server: port: 9002 \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index ad5a9c1..36313ac 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -8,5 +8,9 @@ spring: hibernate: ddl-auto: update + #disable liquibase at start-up + liquibase: + enabled: false + server: port: 8999 \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml deleted file mode 100644 index 8ad4178..0000000 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ /dev/null @@ -1,3 +0,0 @@ -databaseChangeLog: - - includeAll: - path: db/changelog/changes \ No newline at end of file From 1243a51e3ec23d080b3431f397ecb0089362ca26 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Tue, 31 Aug 2021 13:31:14 +0200 Subject: [PATCH 16/18] Add a column to CalculationModel table --- .../calcul/domain/model/CalculationModel.java | 6 ++ .../calcul/domain/model/CalculationType.java | 55 ++++++++++++------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java index 3e30f55..510e06e 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationModel.java @@ -4,6 +4,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.Transient; import lombok.Data; import lombok.NoArgsConstructor; @@ -23,14 +24,18 @@ public class CalculationModel { private Integer leftArgument; private Integer rightArgument; + @Transient private CalculationType type; private Integer solution; private String formattedSolution; + private String typeSymbol; public CalculationModel(CalculationType calculationType, int leftArgument, int rightArgument) { type = calculationType; this.leftArgument = leftArgument; this.rightArgument = rightArgument; + this.typeSymbol = CalculationType.toSymbol(calculationType); + } /** @@ -41,6 +46,7 @@ public CalculationModel(CalculationType calculationType, int leftArgument, int r this.leftArgument = leftArgument; this.rightArgument = rightArgument; this.solution = solution; + this.typeSymbol = CalculationType.toSymbol(calculationType); } /** diff --git a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationType.java b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationType.java index 40f83d8..d7d561a 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationType.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/domain/model/CalculationType.java @@ -1,26 +1,41 @@ package tech.zerofiltre.testing.calcul.domain.model; public enum CalculationType { - ADDITION, - MULTIPLICATION, - DIVISION, - SUBTRACTION, - CONVERSION; + ADDITION, + MULTIPLICATION, + DIVISION, + SUBTRACTION, + CONVERSION; - public static CalculationType fromSymbol(String operation) { - switch (operation) { - case "+": - return ADDITION; - case "-": - return SUBTRACTION; - case "/": - return DIVISION; - case "*": - return MULTIPLICATION; - case "x": - return MULTIPLICATION; - default: - throw new UnsupportedOperationException("Not implemented yet"); - } + public static CalculationType fromSymbol(String operation) { + switch (operation) { + case "+": + return ADDITION; + case "-": + return SUBTRACTION; + case "/": + return DIVISION; + case "*": + return MULTIPLICATION; + case "x": + return MULTIPLICATION; + default: + throw new UnsupportedOperationException("Not implemented yet"); } + } + + public static String toSymbol(CalculationType type) { + switch (type) { + case ADDITION: + return "+"; + case SUBTRACTION: + return "-"; + case DIVISION: + return "/"; + case MULTIPLICATION: + return "*"; + default: + throw new UnsupportedOperationException("Not implemented yet"); + } + } } From 04144bf30b6f4e1ac896871e75719d8712abba59 Mon Sep 17 00:00:00 2001 From: philippe SIMO Date: Tue, 31 Aug 2021 16:46:49 +0200 Subject: [PATCH 17/18] locate db host as host.docker.internal --- src/main/resources/application-dev.yaml | 2 +- src/main/resources/application-prod.yaml | 2 +- src/main/resources/application-uat.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index 200ed7a..4b31e1f 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:mysql://localhost:3307/calculator?serverTimezone=UTC + url: jdbc:mysql://host.docker.internal:3307/calculator?serverTimezone=UTC username: root password: my-secret-pw diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index a4ee265..5ecb30b 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:mysql://localhost:3309/calculator?serverTimezone=UTC + url: jdbc:mysql://host.docker.internal:3309/calculator?serverTimezone=UTC username: root password: my-secret-pw diff --git a/src/main/resources/application-uat.yaml b/src/main/resources/application-uat.yaml index 86edf80..a99b7f4 100644 --- a/src/main/resources/application-uat.yaml +++ b/src/main/resources/application-uat.yaml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:mysql://localhost:3308/calculator?serverTimezone=UTC + url: jdbc:mysql://host.docker.internal:3308/calculator?serverTimezone=UTC username: root password: my-secret-pw From a7c708d4e27923616c445fa09572b0a7920ae5eb Mon Sep 17 00:00:00 2001 From: Nguedjang Kamgang Blondel Aurelie <74322332+Aurelie-Kamgang@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:07:09 +0100 Subject: [PATCH 18/18] update m2ch6_2 branch --- README.md | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cfab93..b2843f3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,117 @@ # Dépôt des sources JAVA pour cours CICD -Sources accompagnant le cours "Continuous Integration, Continuous Delivery" +1/ Installation de PostgreSQL + +docker run -d --name calculator-psql -p 5433:5432 -e POSTGRES_DB=calculator -e POSTGRES_PASSWORD=mysecretpassword postgres + +docker run -d --name calculator-psql-dev -p 5434:5432 -e POSTGRES_DB=calculator -e POSTGRES_PASSWORD=mysecretpassword postgres + +docker run -d --name calculator-psql-uat -p 5435:5432 -e POSTGRES_DB=calculator -e POSTGRES_PASSWORD=mysecretpassword postgres + +docker run -d --name calculator-psql-prod -p 5436:5432 -e POSTGRES_DB=calculator -e POSTGRES_PASSWORD=mysecretpassword postgres + +Le téléchargement de Postgres se fera automatiquement + + +1/ Installation mySQL + +a/ Serveur + +docker run -d --name calculator-mysql -p 3306:3306 -e MYSQL_DATABASE=calculator -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql + +docker run -d --name calculator-mysql-dev -p 3307:3306 -e MYSQL_DATABASE=calculator -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql + +docker run -d --name calculator-mysql-uat -p 3308:3306 -e MYSQL_DATABASE=calculator -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql + +docker run -d --name calculator-mysql-prod -p 3309:3306 -e MYSQL_DATABASE=calculator -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql + +b/ Client : Mysql workbench + +https://dev.mysql.com/downloads/file/?id=505953 + + + + + + + +2/ Générer la différence entre les différentes bases (lorsque vous faite un commit avec git, vous soumettez une différence) + + - Se déplacer sur la branche : m2ch6_1 + + - Lancer l'application en local + - 1 table sera générée dans la base de données locale + - Créer des données dans la bd locale et les appliquer dans la bd de dev en exécutant des opérations sur l'application locale + - Générer la différence entre la base locale et la base de données et celle de dev + + + + +mvn liquibase:diff -Pdev\ + -Dliquibase.url="jdbc:mysql://localhost:3307/calculator?serverTimezone=UTC"\ + -Dliquibase.username="root"\ + -Dliquibase.password="my-secret-pw"\ + -Dliquibase.referenceUrl="jdbc:mysql://localhost:3306/calculator?serverTimezone=UTC"\ + -Dliquibase.referenceUsername="root"\ + -Dliquibase.referencePassword="my-secret-pw" + + ----------------------------------------------------------------------- + + Si des soucis de génération pour file not found, créer des fichiers .keep dans les dossiers vides. + + Un fichier de changelog est généré dans le dossier dev. + + - appliquer les changements + +mvn liquibase:update -Pdev\ + -Dliquibase.url="jdbc:mysql://localhost:3307/calculator?serverTimezone=UTC"\ + -Dliquibase.username="root"\ + -Dliquibase.password="my-secret-pw" + + + + + + + +3 - Modifier le schéma de la BD et générer de nouveau les différences puis appliquer à dev + + - Se placer sur la branche m2ch6_2 + + - Générer la différence + + - Appliquer la différence + + + + + + + +4 - Intégration au pipeline afin d'appliquer automatiquement la différence lors du démarrage. + + + Se placer sur la branche m2ch6 + + Générer la diff avec les bd UAT + +mvn liquibase:diff -Puat\ + -Dliquibase.url="jdbc:mysql://localhost:3308/calculator?serverTimezone=UTC"\ + -Dliquibase.username="root"\ + -Dliquibase.password="my-secret-pw"\ + -Dliquibase.referenceUrl="jdbc:mysql://localhost:3306/calculator?serverTimezone=UTC"\ + -Dliquibase.referenceUsername="root"\ + -Dliquibase.referencePassword="my-secret-pw" + + + Générer la diff avec la bd PROD + +mvn liquibase:diff -Puat\ + -Dliquibase.url="jdbc:mysql://localhost:3309/calculator?serverTimezone=UTC"\ + -Dliquibase.username="root"\ + -Dliquibase.password="my-secret-pw"\ + -Dliquibase.referenceUrl="jdbc:mysql://localhost:3306/calculator?serverTimezone=UTC"\ + -Dliquibase.referenceUsername="root"\ + -Dliquibase.referencePassword="my-secret-pw" + +Pousser les changements et mettre en PROD tel que vu au chapître précédent