149aac325SShawn O. Pearce /* 249aac325SShawn O. Pearce * Copyright (C) 2009, Google Inc. 3d8056995SRobin Rosenberg * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com> 4*5c5f7c6bSMatthias Sohn * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com> and others 549aac325SShawn O. Pearce * 6*5c5f7c6bSMatthias Sohn * This program and the accompanying materials are made available under the 7*5c5f7c6bSMatthias Sohn * terms of the Eclipse Distribution License v. 1.0 which is available at 8*5c5f7c6bSMatthias Sohn * https://www.eclipse.org/org/documents/edl-v10.php. 949aac325SShawn O. Pearce * 10*5c5f7c6bSMatthias Sohn * SPDX-License-Identifier: BSD-3-Clause 1149aac325SShawn O. Pearce */ 1249aac325SShawn O. Pearce 1349aac325SShawn O. Pearce package org.eclipse.jgit.junit; 1449aac325SShawn O. Pearce 15797ebba3SRobin Rosenberg import java.io.File; 16d8056995SRobin Rosenberg import java.io.IOException; 1741a972cdSAndrey Loskutov import java.lang.reflect.Field; 18709cd529SDaniel Megert import java.text.DateFormat; 19709cd529SDaniel Megert import java.text.SimpleDateFormat; 2081f9c184SShawn Pearce import java.time.Duration; 2149aac325SShawn O. Pearce import java.util.HashMap; 223a4fa527SRobin Rosenberg import java.util.Locale; 2349aac325SShawn O. Pearce import java.util.Map; 2449aac325SShawn O. Pearce import java.util.TimeZone; 2581f9c184SShawn Pearce import java.util.concurrent.TimeUnit; 2649aac325SShawn O. Pearce 27d8056995SRobin Rosenberg import org.eclipse.jgit.errors.ConfigInvalidException; 28797ebba3SRobin Rosenberg import org.eclipse.jgit.lib.Config; 2949aac325SShawn O. Pearce import org.eclipse.jgit.lib.Constants; 30f383206aSMatthias Sohn import org.eclipse.jgit.lib.StoredConfig; 31ad5238dcSShawn O. Pearce import org.eclipse.jgit.storage.file.FileBasedConfig; 32936e4ab2SMarc Strapetz import org.eclipse.jgit.util.FS; 3349aac325SShawn O. Pearce import org.eclipse.jgit.util.SystemReader; 3481f9c184SShawn Pearce import org.eclipse.jgit.util.time.MonotonicClock; 3581f9c184SShawn Pearce import org.eclipse.jgit.util.time.ProposedTimestamp; 3649aac325SShawn O. Pearce 37069040ddSTerry Parker /** 38a90b75b4SMatthias Sohn * Mock {@link org.eclipse.jgit.util.SystemReader} for tests. 39069040ddSTerry Parker */ 4049aac325SShawn O. Pearce public class MockSystemReader extends SystemReader { 41ee40efceSDavid Pursehouse private static final class MockConfig extends FileBasedConfig { MockConfig(File cfgLocation, FS fs)42797ebba3SRobin Rosenberg private MockConfig(File cfgLocation, FS fs) { 43797ebba3SRobin Rosenberg super(cfgLocation, fs); 44797ebba3SRobin Rosenberg } 4549aac325SShawn O. Pearce 46d8056995SRobin Rosenberg @Override load()47d8056995SRobin Rosenberg public void load() throws IOException, ConfigInvalidException { 48d8056995SRobin Rosenberg // Do nothing 495c780b38SShawn O. Pearce } 505c780b38SShawn O. Pearce 515c780b38SShawn O. Pearce @Override save()5265cee6ccSMatthias Sohn public void save() throws IOException { 5365cee6ccSMatthias Sohn // Do nothing 5465cee6ccSMatthias Sohn } 5565cee6ccSMatthias Sohn 5665cee6ccSMatthias Sohn @Override isOutdated()575c780b38SShawn O. Pearce public boolean isOutdated() { 585c780b38SShawn O. Pearce return false; 595c780b38SShawn O. Pearce } 609add6d3eSMatthias Sohn 619add6d3eSMatthias Sohn @Override toString()629add6d3eSMatthias Sohn public String toString() { 639add6d3eSMatthias Sohn return "MockConfig"; 649add6d3eSMatthias Sohn } 65797ebba3SRobin Rosenberg } 66797ebba3SRobin Rosenberg 67069040ddSTerry Parker long now = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009 68069040ddSTerry Parker 693b444863SDavid Pursehouse final Map<String, String> values = new HashMap<>(); 70797ebba3SRobin Rosenberg 71f383206aSMatthias Sohn private FileBasedConfig userGitConfig; 72797ebba3SRobin Rosenberg 73838b5a84SMatthias Sohn private FileBasedConfig jgitConfig; 74838b5a84SMatthias Sohn 75797ebba3SRobin Rosenberg FileBasedConfig systemGitConfig; 76797ebba3SRobin Rosenberg 77a90b75b4SMatthias Sohn /** 78f383206aSMatthias Sohn * Set the user-level git config 79f383206aSMatthias Sohn * 80f383206aSMatthias Sohn * @param userGitConfig 81f383206aSMatthias Sohn * set another user-level git config 82f383206aSMatthias Sohn * @return the old user-level git config 83f383206aSMatthias Sohn */ setUserGitConfig(FileBasedConfig userGitConfig)84f383206aSMatthias Sohn public FileBasedConfig setUserGitConfig(FileBasedConfig userGitConfig) { 85f383206aSMatthias Sohn FileBasedConfig old = this.userGitConfig; 86f383206aSMatthias Sohn this.userGitConfig = userGitConfig; 87f383206aSMatthias Sohn return old; 88f383206aSMatthias Sohn } 89f383206aSMatthias Sohn 90f383206aSMatthias Sohn /** 91838b5a84SMatthias Sohn * Set the jgit config stored at $XDG_CONFIG_HOME/jgit/config 92838b5a84SMatthias Sohn * 93838b5a84SMatthias Sohn * @param jgitConfig 94838b5a84SMatthias Sohn * set the jgit configuration 95838b5a84SMatthias Sohn */ setJGitConfig(FileBasedConfig jgitConfig)96838b5a84SMatthias Sohn public void setJGitConfig(FileBasedConfig jgitConfig) { 97838b5a84SMatthias Sohn this.jgitConfig = jgitConfig; 98838b5a84SMatthias Sohn } 99838b5a84SMatthias Sohn 100838b5a84SMatthias Sohn /** 101f383206aSMatthias Sohn * Set the system-level git config 102f383206aSMatthias Sohn * 103f383206aSMatthias Sohn * @param systemGitConfig 104f383206aSMatthias Sohn * the new system-level git config 105f383206aSMatthias Sohn * @return the old system-level config 106f383206aSMatthias Sohn */ setSystemGitConfig(FileBasedConfig systemGitConfig)107f383206aSMatthias Sohn public FileBasedConfig setSystemGitConfig(FileBasedConfig systemGitConfig) { 108f383206aSMatthias Sohn FileBasedConfig old = this.systemGitConfig; 109f383206aSMatthias Sohn this.systemGitConfig = systemGitConfig; 110f383206aSMatthias Sohn return old; 111f383206aSMatthias Sohn } 112f383206aSMatthias Sohn 113f383206aSMatthias Sohn /** 114a90b75b4SMatthias Sohn * Constructor for <code>MockSystemReader</code> 115a90b75b4SMatthias Sohn */ MockSystemReader()116797ebba3SRobin Rosenberg public MockSystemReader() { 117797ebba3SRobin Rosenberg init(Constants.OS_USER_NAME_KEY); 118797ebba3SRobin Rosenberg init(Constants.GIT_AUTHOR_NAME_KEY); 119797ebba3SRobin Rosenberg init(Constants.GIT_AUTHOR_EMAIL_KEY); 120797ebba3SRobin Rosenberg init(Constants.GIT_COMMITTER_NAME_KEY); 121797ebba3SRobin Rosenberg init(Constants.GIT_COMMITTER_EMAIL_KEY); 12203e860a7SChristian Halstrick setProperty(Constants.OS_USER_DIR, "."); 123797ebba3SRobin Rosenberg userGitConfig = new MockConfig(null, null); 124838b5a84SMatthias Sohn jgitConfig = new MockConfig(null, null); 125797ebba3SRobin Rosenberg systemGitConfig = new MockConfig(null, null); 12642d7565bSRobin Rosenberg setCurrentPlatform(); 12749aac325SShawn O. Pearce } 12849aac325SShawn O. Pearce init(String n)1296d370d83SHan-Wen Nienhuys private void init(String n) { 13049aac325SShawn O. Pearce setProperty(n, n); 13149aac325SShawn O. Pearce } 13249aac325SShawn O. Pearce 133a90b75b4SMatthias Sohn /** 134a90b75b4SMatthias Sohn * Clear properties 135a90b75b4SMatthias Sohn */ clearProperties()13649aac325SShawn O. Pearce public void clearProperties() { 13749aac325SShawn O. Pearce values.clear(); 13849aac325SShawn O. Pearce } 13949aac325SShawn O. Pearce 140a90b75b4SMatthias Sohn /** 141a90b75b4SMatthias Sohn * Set a property 142a90b75b4SMatthias Sohn * 143a90b75b4SMatthias Sohn * @param key 144a90b75b4SMatthias Sohn * @param value 145a90b75b4SMatthias Sohn */ setProperty(String key, String value)14649aac325SShawn O. Pearce public void setProperty(String key, String value) { 14749aac325SShawn O. Pearce values.put(key, value); 14849aac325SShawn O. Pearce } 14949aac325SShawn O. Pearce 150a90b75b4SMatthias Sohn /** {@inheritDoc} */ 15149aac325SShawn O. Pearce @Override getenv(String variable)15249aac325SShawn O. Pearce public String getenv(String variable) { 15349aac325SShawn O. Pearce return values.get(variable); 15449aac325SShawn O. Pearce } 15549aac325SShawn O. Pearce 156a90b75b4SMatthias Sohn /** {@inheritDoc} */ 15749aac325SShawn O. Pearce @Override getProperty(String key)15849aac325SShawn O. Pearce public String getProperty(String key) { 15949aac325SShawn O. Pearce return values.get(key); 16049aac325SShawn O. Pearce } 16149aac325SShawn O. Pearce 162a90b75b4SMatthias Sohn /** {@inheritDoc} */ 16349aac325SShawn O. Pearce @Override openUserConfig(Config parent, FS fs)164797ebba3SRobin Rosenberg public FileBasedConfig openUserConfig(Config parent, FS fs) { 165797ebba3SRobin Rosenberg assert parent == null || parent == systemGitConfig; 16649aac325SShawn O. Pearce return userGitConfig; 16749aac325SShawn O. Pearce } 16849aac325SShawn O. Pearce 169a90b75b4SMatthias Sohn /** {@inheritDoc} */ 17049aac325SShawn O. Pearce @Override openSystemConfig(Config parent, FS fs)171797ebba3SRobin Rosenberg public FileBasedConfig openSystemConfig(Config parent, FS fs) { 172797ebba3SRobin Rosenberg assert parent == null; 173797ebba3SRobin Rosenberg return systemGitConfig; 174797ebba3SRobin Rosenberg } 175797ebba3SRobin Rosenberg 176f383206aSMatthias Sohn @Override getUserConfig()177f383206aSMatthias Sohn public StoredConfig getUserConfig() 178f383206aSMatthias Sohn throws IOException, ConfigInvalidException { 179f383206aSMatthias Sohn return userGitConfig; 180f383206aSMatthias Sohn } 181f383206aSMatthias Sohn 182f383206aSMatthias Sohn @Override getJGitConfig()183838b5a84SMatthias Sohn public FileBasedConfig getJGitConfig() { 184838b5a84SMatthias Sohn return jgitConfig; 185838b5a84SMatthias Sohn } 186838b5a84SMatthias Sohn 187838b5a84SMatthias Sohn @Override getSystemConfig()188f383206aSMatthias Sohn public StoredConfig getSystemConfig() 189f383206aSMatthias Sohn throws IOException, ConfigInvalidException { 190f383206aSMatthias Sohn return systemGitConfig; 191f383206aSMatthias Sohn } 192f383206aSMatthias Sohn 193a90b75b4SMatthias Sohn /** {@inheritDoc} */ 194797ebba3SRobin Rosenberg @Override getHostname()19549aac325SShawn O. Pearce public String getHostname() { 19649aac325SShawn O. Pearce return "fake.host.example.com"; 19749aac325SShawn O. Pearce } 19849aac325SShawn O. Pearce 199a90b75b4SMatthias Sohn /** {@inheritDoc} */ 20049aac325SShawn O. Pearce @Override getCurrentTime()20149aac325SShawn O. Pearce public long getCurrentTime() { 202069040ddSTerry Parker return now; 203069040ddSTerry Parker } 204069040ddSTerry Parker 205a90b75b4SMatthias Sohn /** {@inheritDoc} */ 20681f9c184SShawn Pearce @Override getClock()20781f9c184SShawn Pearce public MonotonicClock getClock() { 20884fc5c90SCarsten Hammer return () -> { 20981f9c184SShawn Pearce long t = getCurrentTime(); 21081f9c184SShawn Pearce return new ProposedTimestamp() { 21184fc5c90SCarsten Hammer 21281f9c184SShawn Pearce @Override 21381f9c184SShawn Pearce public long read(TimeUnit unit) { 21481f9c184SShawn Pearce return unit.convert(t, TimeUnit.MILLISECONDS); 21581f9c184SShawn Pearce } 21681f9c184SShawn Pearce 21781f9c184SShawn Pearce @Override 21881f9c184SShawn Pearce public void blockUntil(Duration maxWait) { 21981f9c184SShawn Pearce // Do not wait. 22081f9c184SShawn Pearce } 22181f9c184SShawn Pearce }; 22281f9c184SShawn Pearce }; 22381f9c184SShawn Pearce } 22481f9c184SShawn Pearce 225069040ddSTerry Parker /** 226069040ddSTerry Parker * Adjusts the current time in seconds. 227069040ddSTerry Parker * 228069040ddSTerry Parker * @param secDelta 229069040ddSTerry Parker * number of seconds to add to the current time. 2302cdc130dSMatthias Sohn * @since 4.2 231069040ddSTerry Parker */ 2326d370d83SHan-Wen Nienhuys public void tick(int secDelta) { 233069040ddSTerry Parker now += secDelta * 1000L; 23449aac325SShawn O. Pearce } 23549aac325SShawn O. Pearce 236a90b75b4SMatthias Sohn /** {@inheritDoc} */ 23749aac325SShawn O. Pearce @Override 23849aac325SShawn O. Pearce public int getTimezone(long when) { 23906b183f9SRobin Rosenberg return getTimeZone().getOffset(when) / (60 * 1000); 24049aac325SShawn O. Pearce } 241797ebba3SRobin Rosenberg 242a90b75b4SMatthias Sohn /** {@inheritDoc} */ 24306b183f9SRobin Rosenberg @Override 24406b183f9SRobin Rosenberg public TimeZone getTimeZone() { 24506b183f9SRobin Rosenberg return TimeZone.getTimeZone("GMT-03:30"); 24606b183f9SRobin Rosenberg } 2473a4fa527SRobin Rosenberg 248a90b75b4SMatthias Sohn /** {@inheritDoc} */ 2493a4fa527SRobin Rosenberg @Override 2503a4fa527SRobin Rosenberg public Locale getLocale() { 2513a4fa527SRobin Rosenberg return Locale.US; 2523a4fa527SRobin Rosenberg } 253dfcb43efSRobin Rosenberg 254a90b75b4SMatthias Sohn /** {@inheritDoc} */ 255709cd529SDaniel Megert @Override 256709cd529SDaniel Megert public SimpleDateFormat getSimpleDateFormat(String pattern) { 257709cd529SDaniel Megert return new SimpleDateFormat(pattern, getLocale()); 258709cd529SDaniel Megert } 259709cd529SDaniel Megert 260a90b75b4SMatthias Sohn /** {@inheritDoc} */ 261709cd529SDaniel Megert @Override 262709cd529SDaniel Megert public DateFormat getDateTimeInstance(int dateStyle, int timeStyle) { 263709cd529SDaniel Megert return DateFormat 264709cd529SDaniel Megert .getDateTimeInstance(dateStyle, timeStyle, getLocale()); 265709cd529SDaniel Megert } 266709cd529SDaniel Megert 267dfcb43efSRobin Rosenberg /** 268dfcb43efSRobin Rosenberg * Assign some properties for the currently executing platform 269dfcb43efSRobin Rosenberg */ 270dfcb43efSRobin Rosenberg public void setCurrentPlatform() { 27141a972cdSAndrey Loskutov resetOsNames(); 272dfcb43efSRobin Rosenberg setProperty("os.name", System.getProperty("os.name")); 273dfcb43efSRobin Rosenberg setProperty("file.separator", System.getProperty("file.separator")); 274dfcb43efSRobin Rosenberg setProperty("path.separator", System.getProperty("path.separator")); 275dfcb43efSRobin Rosenberg setProperty("line.separator", System.getProperty("line.separator")); 276dfcb43efSRobin Rosenberg } 277dfcb43efSRobin Rosenberg 278dfcb43efSRobin Rosenberg /** 279dfcb43efSRobin Rosenberg * Emulate Windows 280dfcb43efSRobin Rosenberg */ 281dfcb43efSRobin Rosenberg public void setWindows() { 28241a972cdSAndrey Loskutov resetOsNames(); 283dfcb43efSRobin Rosenberg setProperty("os.name", "Windows"); 284dfcb43efSRobin Rosenberg setProperty("file.separator", "\\"); 285dfcb43efSRobin Rosenberg setProperty("path.separator", ";"); 286dfcb43efSRobin Rosenberg setProperty("line.separator", "\r\n"); 2873226e35dSChristian Halstrick setPlatformChecker(); 288dfcb43efSRobin Rosenberg } 289dfcb43efSRobin Rosenberg 290dfcb43efSRobin Rosenberg /** 291dfcb43efSRobin Rosenberg * Emulate Unix 292dfcb43efSRobin Rosenberg */ 293dfcb43efSRobin Rosenberg public void setUnix() { 29441a972cdSAndrey Loskutov resetOsNames(); 295dfcb43efSRobin Rosenberg setProperty("os.name", "*nix"); // Essentially anything but Windows 296dfcb43efSRobin Rosenberg setProperty("file.separator", "/"); 297dfcb43efSRobin Rosenberg setProperty("path.separator", ":"); 298dfcb43efSRobin Rosenberg setProperty("line.separator", "\n"); 2993226e35dSChristian Halstrick setPlatformChecker(); 300dfcb43efSRobin Rosenberg } 30141a972cdSAndrey Loskutov 30241a972cdSAndrey Loskutov private void resetOsNames() { 30341a972cdSAndrey Loskutov Field field; 30441a972cdSAndrey Loskutov try { 30541a972cdSAndrey Loskutov field = SystemReader.class.getDeclaredField("isWindows"); 30641a972cdSAndrey Loskutov field.setAccessible(true); 30741a972cdSAndrey Loskutov field.set(null, null); 30841a972cdSAndrey Loskutov field = SystemReader.class.getDeclaredField("isMacOS"); 30941a972cdSAndrey Loskutov field.setAccessible(true); 31041a972cdSAndrey Loskutov field.set(null, null); 31141a972cdSAndrey Loskutov } catch (Exception e) { 31241a972cdSAndrey Loskutov e.printStackTrace(); 31341a972cdSAndrey Loskutov } 31441a972cdSAndrey Loskutov } 3159add6d3eSMatthias Sohn 3169add6d3eSMatthias Sohn @Override 3179add6d3eSMatthias Sohn public String toString() { 3189add6d3eSMatthias Sohn return "MockSystemReader"; 3199add6d3eSMatthias Sohn } 3209add6d3eSMatthias Sohn 321838b5a84SMatthias Sohn @Override 322838b5a84SMatthias Sohn public FileBasedConfig openJGitConfig(Config parent, FS fs) { 323838b5a84SMatthias Sohn return jgitConfig; 324838b5a84SMatthias Sohn } 325838b5a84SMatthias Sohn 32649aac325SShawn O. Pearce } 327