1 /* 2 * Copyright 2016 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.cloud.testing; 18 19 import com.google.api.client.util.Charsets; 20 import com.google.cloud.ServiceOptions; 21 import com.google.cloud.testing.BaseEmulatorHelper.EmulatorRunner; 22 import com.google.common.collect.ImmutableList; 23 import java.io.ByteArrayInputStream; 24 import java.io.EOFException; 25 import java.io.File; 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.net.URL; 29 import java.net.URLConnection; 30 import java.net.URLStreamHandler; 31 import java.util.List; 32 import java.util.concurrent.TimeoutException; 33 import java.util.logging.Logger; 34 import org.easymock.EasyMock; 35 import org.junit.Test; 36 import org.threeten.bp.Duration; 37 38 public class BaseEmulatorHelperTest { 39 40 private static final String BLOCK_UNTIL = "Block until"; 41 42 private static class TestEmulatorHelper extends BaseEmulatorHelper<ServiceOptions> { 43 44 private final List<EmulatorRunner> runners; 45 private final String blockUntil; 46 TestEmulatorHelper(List<EmulatorRunner> runners, String blockUntil)47 private TestEmulatorHelper(List<EmulatorRunner> runners, String blockUntil) { 48 super("emulator", 1, "project"); 49 this.runners = runners; 50 this.blockUntil = blockUntil; 51 } 52 53 @Override getEmulatorRunners()54 protected List<EmulatorRunner> getEmulatorRunners() { 55 return runners; 56 } 57 58 @Override getLogger()59 protected Logger getLogger() { 60 return Logger.getLogger(TestEmulatorHelper.class.getName()); 61 } 62 63 @Override getOptions()64 public ServiceOptions getOptions() { 65 return null; 66 } 67 68 @Override start()69 public void start() throws IOException, InterruptedException { 70 startProcess(blockUntil); 71 } 72 73 @Override stop(Duration timeout)74 public void stop(Duration timeout) throws IOException, InterruptedException, TimeoutException { 75 waitForProcess(timeout); 76 } 77 78 @Override reset()79 public void reset() throws IOException { 80 // do nothing 81 } 82 } 83 84 @Test testEmulatorHelper()85 public void testEmulatorHelper() throws IOException, InterruptedException, TimeoutException { 86 Process process = EasyMock.createStrictMock(Process.class); 87 InputStream stream = new ByteArrayInputStream(BLOCK_UNTIL.getBytes(Charsets.UTF_8)); 88 EmulatorRunner emulatorRunner = EasyMock.createStrictMock(EmulatorRunner.class); 89 EasyMock.expect(process.getInputStream()).andReturn(stream); 90 EasyMock.expect(emulatorRunner.isAvailable()).andReturn(true); 91 emulatorRunner.start(); 92 EasyMock.expectLastCall(); 93 EasyMock.expect(emulatorRunner.getProcess()).andReturn(process); 94 emulatorRunner.waitFor(Duration.ofMinutes(1)); 95 EasyMock.expectLastCall().andReturn(0); 96 EasyMock.replay(process, emulatorRunner); 97 TestEmulatorHelper helper = 98 new TestEmulatorHelper(ImmutableList.of(emulatorRunner), BLOCK_UNTIL); 99 helper.start(); 100 helper.stop(Duration.ofMinutes(1)); 101 EasyMock.verify(); 102 } 103 104 @Test testEmulatorHelperDownloadWithRetries()105 public void testEmulatorHelperDownloadWithRetries() 106 throws IOException, InterruptedException, TimeoutException { 107 String mockExternalForm = "mockExternalForm"; 108 String mockInputStream = "mockInputStream"; 109 String mockProtocol = "mockProtocol"; 110 String mockFile = "mockFile"; 111 String mockAccessToken = "mockAccessToken"; 112 String mockCommandText = "mockCommandText"; 113 114 MockURLStreamHandler mockURLStreamHandler = EasyMock.createMock(MockURLStreamHandler.class); 115 URLConnection mockURLConnection = EasyMock.mock(URLConnection.class); 116 117 EasyMock.expect(mockURLStreamHandler.toExternalForm(EasyMock.anyObject(URL.class))) 118 .andReturn(mockExternalForm) 119 .anyTimes(); 120 EasyMock.expect(mockURLConnection.getInputStream()) 121 .andReturn(new ByteArrayInputStream(mockInputStream.getBytes())) 122 .anyTimes(); 123 mockURLConnection.setRequestProperty("Authorization", "Bearer " + mockAccessToken); 124 EasyMock.expect(mockURLStreamHandler.openConnection(EasyMock.anyObject(URL.class))) 125 .andThrow(new EOFException()) 126 .times(1); 127 EasyMock.expect(mockURLStreamHandler.openConnection(EasyMock.anyObject(URL.class))) 128 .andReturn(mockURLConnection) 129 .times(1); 130 EasyMock.replay(mockURLStreamHandler, mockURLConnection); 131 132 URL url = new URL(mockProtocol, null, 0, mockFile, mockURLStreamHandler); 133 BaseEmulatorHelper.DownloadableEmulatorRunner runner = 134 new BaseEmulatorHelper.DownloadableEmulatorRunner( 135 ImmutableList.of(mockCommandText), url, null, mockAccessToken); 136 137 File cachedFile = new File(System.getProperty("java.io.tmpdir"), mockExternalForm); 138 cachedFile.delete(); // Clear the cached version so we're always testing the download 139 140 runner.start(); 141 142 EasyMock.verify(); 143 144 cachedFile.delete(); // Cleanup 145 } 146 147 @Test testEmulatorHelperMultipleRunners()148 public void testEmulatorHelperMultipleRunners() 149 throws IOException, InterruptedException, TimeoutException { 150 Process process = EasyMock.createStrictMock(Process.class); 151 InputStream stream = new ByteArrayInputStream(BLOCK_UNTIL.getBytes(Charsets.UTF_8)); 152 EmulatorRunner firstRunner = EasyMock.createStrictMock(EmulatorRunner.class); 153 EmulatorRunner secondRunner = EasyMock.createStrictMock(EmulatorRunner.class); 154 EasyMock.expect(process.getInputStream()).andReturn(stream); 155 EasyMock.expect(firstRunner.isAvailable()).andReturn(false); 156 EasyMock.expect(secondRunner.isAvailable()).andReturn(true); 157 secondRunner.start(); 158 EasyMock.expectLastCall(); 159 EasyMock.expect(secondRunner.getProcess()).andReturn(process); 160 secondRunner.waitFor(Duration.ofMinutes(1)); 161 EasyMock.expectLastCall().andReturn(0); 162 EasyMock.replay(process, secondRunner); 163 TestEmulatorHelper helper = 164 new TestEmulatorHelper(ImmutableList.of(firstRunner, secondRunner), BLOCK_UNTIL); 165 helper.start(); 166 helper.stop(Duration.ofMinutes(1)); 167 EasyMock.verify(); 168 } 169 170 /** 171 * URLStreamHandler has a protected method which needs to be mocked, so we need our own 172 * implementation in this package 173 */ 174 private class MockURLStreamHandler extends URLStreamHandler { 175 @Override openConnection(URL u)176 protected URLConnection openConnection(URL u) throws IOException { 177 return null; 178 } 179 180 @Override toExternalForm(URL u)181 protected String toExternalForm(URL u) { 182 return null; 183 } 184 } 185 } 186