You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2019/06/03 16:29:50 UTC

[sling-org-apache-sling-committer-cli] branch master updated: SLING-8391 - Add support for execution modes

This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new 5aa8622  SLING-8391 - Add support for execution modes
5aa8622 is described below

commit 5aa8622d15195c08f32349e037018c4d1c66e70a
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Jun 3 18:29:40 2019 +0200

    SLING-8391 - Add support for execution modes
    
    * implemented support for execution modes in the update-reporter command
---
 .../cli/impl/release/UpdateReporterCommand.java    |  67 +++++++---
 .../impl/release/UpdateReporterCommandTest.java    | 136 +++++++++++++++++++++
 2 files changed, 185 insertions(+), 18 deletions(-)

diff --git a/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java b/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java
index 48aa621..a53cfae 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java
+++ b/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java
@@ -33,6 +33,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.sling.cli.impl.Command;
 import org.apache.sling.cli.impl.ExecutionContext;
+import org.apache.sling.cli.impl.InputOption;
+import org.apache.sling.cli.impl.UserInput;
 import org.apache.sling.cli.impl.http.HttpClientFactory;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
 import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
@@ -62,29 +64,58 @@ public class UpdateReporterCommand implements Command {
     public void execute(ExecutionContext context) {
         try {
             StagingRepository repository = repoFinder.find(Integer.parseInt(context.getTarget()));
-            
-            try (CloseableHttpClient client = httpClientFactory.newClient() ) {
-                for ( Release release : Release.fromString(repository.getDescription()) ) {
-                    HttpPost post = new HttpPost("https://reporter.apache.org/addrelease.py");
-                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
-                    List<NameValuePair> parameters = new ArrayList<>();
-                    Date now = new Date();
-                    parameters.add(new BasicNameValuePair("date", Long.toString(now.getTime() / 1000)));
-                    parameters.add(new BasicNameValuePair("committee", "sling"));
-                    parameters.add(new BasicNameValuePair("version", release.getFullName()));
-                    parameters.add(new BasicNameValuePair("xdate", simpleDateFormat.format(now)));
-                    post.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8));
-                    try (CloseableHttpResponse response = client.execute(post)) {
-                        if (response.getStatusLine().getStatusCode() != 200) {
-                            throw new IOException(String.format("The Apache Reporter System update failed. Got response code %s instead of " +
-                                    "200.", response.getStatusLine().getStatusCode()));
-                        }
+            List<Release> releases = Release.fromString(repository.getDescription());
+            String releaseReleases = releases.size() > 1 ? "releases" : "release";
+            switch (context.getMode()) {
+                case DRY_RUN:
+                    LOGGER.info("The following {} would be added to the Apache Reporter System:", releaseReleases);
+                    releases.forEach(release -> LOGGER.info("  - {}", release.getFullName()));
+                    break;
+                case INTERACTIVE:
+                    StringBuilder question = new StringBuilder(String.format("Should the following %s be added to the Apache Reporter " +
+                            "System?", releaseReleases)).append("\n");
+                    releases.forEach(release -> question.append("  - ").append(release.getFullName()).append("\n"));
+                    InputOption answer = UserInput.yesNo(question.toString(), InputOption.YES);
+                    if (InputOption.YES.equals(answer)) {
+                        LOGGER.info("Updating the Apache Reporter System...");
+                        updateReporter(releases);
+                        LOGGER.info("Done.");
+                    } else if (InputOption.NO.equals(answer)) {
+                        LOGGER.info("Aborted updating the Apache Reporter System.");
                     }
-                }
+                    break;
+                case AUTO:
+                    LOGGER.info("The following {} will be added to the Apache Reporter System:", releaseReleases);
+                    releases.forEach(release -> LOGGER.info("  - {}", release.getFullName()));
+                    updateReporter(releases);
+                    LOGGER.info("Done.");
             }
+
         } catch (IOException e) {
             LOGGER.error(String.format("Unable to update reporter service; passed command: %s.", context.getTarget()), e);
         }
 
     }
+
+    private void updateReporter(List<Release> releases) throws IOException {
+        try (CloseableHttpClient client = httpClientFactory.newClient()) {
+            for (Release release : releases) {
+                HttpPost post = new HttpPost("https://reporter.apache.org/addrelease.py");
+                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+                List<NameValuePair> parameters = new ArrayList<>();
+                Date now = new Date();
+                parameters.add(new BasicNameValuePair("date", Long.toString(now.getTime() / 1000)));
+                parameters.add(new BasicNameValuePair("committee", "sling"));
+                parameters.add(new BasicNameValuePair("version", release.getFullName()));
+                parameters.add(new BasicNameValuePair("xdate", simpleDateFormat.format(now)));
+                post.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8));
+                try (CloseableHttpResponse response = client.execute(post)) {
+                    if (response.getStatusLine().getStatusCode() != 200) {
+                        throw new IOException(String.format("The Apache Reporter System update failed for release %s. Got response code " +
+                                "%s instead of 200.", release.getFullName(), response.getStatusLine().getStatusCode()));
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/src/test/java/org/apache/sling/cli/impl/release/UpdateReporterCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/UpdateReporterCommandTest.java
new file mode 100644
index 0000000..8af6c63
--- /dev/null
+++ b/src/test/java/org/apache/sling/cli/impl/release/UpdateReporterCommandTest.java
@@ -0,0 +1,136 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
+import org.apache.sling.cli.impl.InputOption;
+import org.apache.sling.cli.impl.UserInput;
+import org.apache.sling.cli.impl.http.HttpClientFactory;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockIgnore({
+    // https://github.com/powermock/powermock/issues/864
+    "com.sun.org.apache.xerces.*",
+    "javax.xml.*",
+    "org.w3c.dom.*"
+})
+public class UpdateReporterCommandTest {
+
+    private CloseableHttpClient client;
+
+    @Rule
+    public final OsgiContext osgiContext = new OsgiContext();
+
+    @Before
+    public void before() throws IOException {
+        StagingRepositoryFinder repositoryFinder = mock(StagingRepositoryFinder.class);
+        StagingRepository stagingRepository = mock(StagingRepository.class);
+        when(stagingRepository.getDescription()).thenReturn("Apache Sling CLI 1, Apache Sling CLI 2");
+        when(repositoryFinder.find(42)).thenReturn(stagingRepository);
+
+        HttpClientFactory httpClientFactory = mock(HttpClientFactory.class);
+        client = mock(CloseableHttpClient.class);
+        when(httpClientFactory.newClient()).thenReturn(client);
+
+        osgiContext.registerService(repositoryFinder);
+        osgiContext.registerService(httpClientFactory);
+    }
+
+    @Test
+    @PrepareForTest({LoggerFactory.class})
+    public void testDryRun() throws Exception {
+        mockStatic(LoggerFactory.class);
+        Logger logger = mock(Logger.class);
+        when(LoggerFactory.getLogger(UpdateReporterCommand.class)).thenReturn(logger);
+
+        osgiContext.registerInjectActivateService(new UpdateReporterCommand());
+        Command updateReporter = osgiContext.getService(Command.class);
+        assertTrue("Expected to retrieve the UpdateReporterCommand from the mocked OSGi environment.",
+                updateReporter instanceof UpdateReporterCommand);
+        updateReporter.execute(new ExecutionContext("42", "--dry-run"));
+        verify(logger).info("The following {} would be added to the Apache Reporter System:", "releases");
+        verify(logger).info("  - {}", "Apache Sling CLI 1");
+        verify(logger).info("  - {}", "Apache Sling CLI 2");
+        verifyNoMoreInteractions(logger);
+    }
+
+    @Test
+    @PrepareForTest({UserInput.class})
+    public void testInteractive() throws Exception {
+        osgiContext.registerInjectActivateService(new UpdateReporterCommand());
+        Command updateReporter = osgiContext.getService(Command.class);
+        assertTrue("Expected to retrieve the UpdateReporterCommand from the mocked OSGi environment.",
+                updateReporter instanceof UpdateReporterCommand);
+        CloseableHttpResponse response = mock(CloseableHttpResponse.class);
+        StatusLine statusLine = mock(StatusLine.class);
+        mockStatic(UserInput.class);
+        String question =
+                "Should the following releases be added to the Apache Reporter System?\n  - Apache Sling CLI 1\n  - Apache Sling CLI 2\n";
+        when(UserInput.yesNo(question, InputOption.YES)).thenReturn(InputOption.YES);
+        when(response.getStatusLine()).thenReturn(statusLine);
+        when(statusLine.getStatusCode()).thenReturn(200);
+        when(client.execute(any())).thenReturn(response);
+        updateReporter.execute(new ExecutionContext("42", "--interactive"));
+        verify(client, times(2)).execute(any());
+    }
+
+    @Test
+    public void testAuto() throws Exception {
+        osgiContext.registerInjectActivateService(new UpdateReporterCommand());
+        Command updateReporter = osgiContext.getService(Command.class);
+        assertTrue("Expected to retrieve the UpdateReporterCommand from the mocked OSGi environment.",
+                updateReporter instanceof UpdateReporterCommand);
+        CloseableHttpResponse response = mock(CloseableHttpResponse.class);
+        StatusLine statusLine = mock(StatusLine.class);
+        when(response.getStatusLine()).thenReturn(statusLine);
+        when(statusLine.getStatusCode()).thenReturn(200);
+        when(client.execute(any())).thenReturn(response);
+        updateReporter.execute(new ExecutionContext("42", "--auto"));
+        verify(client, times(2)).execute(any());
+    }
+
+
+}