Skip to content

Prevent testsuite from reading user settings and data #10170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 11, 2020
14 changes: 5 additions & 9 deletions app/test/processing/app/AbstractGUITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,26 @@
import javax.swing.*;
import java.util.Random;

public abstract class AbstractGUITest {
public abstract class AbstractGUITest extends AbstractWithPreferencesTest {

protected ArduinoFrameFixture window;

@Before
public void startUpTheIDE() throws Exception {
// This relies on AbstractWithPreferencesTest to set up the
// non-gui-specific stuff.

System.setProperty("mrj.version", "whynot"); //makes sense only on osx. See https://github.com/alexruiz/fest-swing-1.x/issues/2#issuecomment-86532042
Runtime.getRuntime().addShutdownHook(new Thread(DeleteFilesOnShutdown.INSTANCE));

FailOnThreadViolationRepaintManager.install();

BaseNoGui.initPlatform();
BaseNoGui.getPlatform().init();
PreferencesData.init(null);
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
Theme.init();
BaseNoGui.getPlatform().setLookAndFeel();
Base.untitledFolder = FileUtils.createTempFolder("untitled" + new Random().nextInt(Integer.MAX_VALUE), ".tmp");
DeleteFilesOnShutdown.add(Base.untitledFolder);

window = GuiActionRunner.execute(new GuiQuery<ArduinoFrameFixture>() {
@Override
protected ArduinoFrameFixture executeInEDT() throws Throwable {
return new ArduinoFrameFixture(new Base(new String[0]).editors.get(0));
return new ArduinoFrameFixture(createBase().editors.get(0));
}
});
}
Expand Down
70 changes: 66 additions & 4 deletions app/test/processing/app/AbstractWithPreferencesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,88 @@

package processing.app;

import cc.arduino.files.DeleteFilesOnShutdown;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.After;

import processing.app.helpers.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Random;
import java.util.List;
import java.util.LinkedList;

public abstract class AbstractWithPreferencesTest {
/**
* Files or directories that will be deleted after each test.
* Subclasses can add files here in @Test or @Before functions.
*/
protected List<File> deleteAfter = new LinkedList<File>();
protected File preferencesFile;

@Before
public void init() throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread(DeleteFilesOnShutdown.INSTANCE));
File settingsDir = Files.createTempDirectory("arduino_test_settings").toFile();
deleteAfter.add(settingsDir);

preferencesFile = new File(settingsDir, "preferences.txt");
File sketchbookDir = new File(settingsDir, "sketchbook");
sketchbookDir.mkdir();

BaseNoGui.initPlatform();
BaseNoGui.getPlatform().init();
PreferencesData.init(null);

PreferencesData.init(preferencesFile);
// Do not read anything from e.g. ~/.arduino15
PreferencesData.set("settings.path", settingsDir.toString());
// Do not read or write the default ~/Arduino sketchbook
PreferencesData.set("sketchbook.path", sketchbookDir.toString());
// Do not perform any update checks
PreferencesData.set("update.check", sketchbookDir.toString());
// Write the defaults, with these changes to file. This allows them
// to be reloaded when creating a Base instance (see getBaseArgs()
// below).
PreferencesData.save();

Theme.init();

BaseNoGui.initPackages();

Base.untitledFolder = FileUtils.createTempFolder("untitled" + new Random().nextInt(Integer.MAX_VALUE), ".tmp");
DeleteFilesOnShutdown.add(Base.untitledFolder);
deleteAfter.add(Base.untitledFolder);
}

/**
* Returns arguments to be passed to the Base constructor or on the
* commandline to set up the created dummy environment.
*/
protected String[] getBaseArgs() {
return new String[] {
// Preferences are loaded (using --preferences-file) before
// processing any other commandline options (e.g. --pref), so only
// use --preferences-file here. Also, this does not affect the
// "action" mode, for tests that require the GUI to be loaded.
"--preferences-file", preferencesFile.toString(),
};
}

/**
* Creates a new instance of Base. Always use this rather than calling
* it directly, to ensure the right settings are used.
*/
protected Base createBase() throws Exception {
Base base = new Base(getBaseArgs());
// Doublecheck that the right preferencesFile was loaded
assertEquals(preferencesFile, PreferencesData.preferencesFile);
return base;
}

@After
public void cleanup() throws IOException {
for (File f : deleteAfter)
FileUtils.recursiveDelete(f);
deleteAfter = new LinkedList<File>();
}
}
91 changes: 47 additions & 44 deletions app/test/processing/app/CommandLineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,32 @@
import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.compress.utils.IOUtils;
import org.fest.assertions.Assertions;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesMap;

public class CommandLineTest {
/**
* This extends AbstractWithPreferencesTest which initializes part of
* the internal Arduino structures. Most of that is not required, but it
* also conveniently sets up a settings directory and preferences file,
* which we can use here (through getBaseArgs()).
*/
public class CommandLineTest extends AbstractWithPreferencesTest {

File buildPath;
File arduinoPath;
private static File buildPath;
private static File arduinoPath;

@Before
public void findBuildPaths() throws Exception {
@BeforeClass
public static void findBuildPaths() throws Exception {
buildPath = new File(System.getProperty("user.dir"));
while (!new File(buildPath, "build").isDirectory()) {
buildPath = buildPath.getParentFile();
Expand All @@ -72,88 +82,81 @@ public void findBuildPaths() throws Exception {
System.out.println("found arduino: " + arduinoPath);
}

public Process runArduino(boolean output, boolean success, File wd, String[] extraArgs) throws IOException, InterruptedException {
Runtime rt = Runtime.getRuntime();

List<String> args = new ArrayList<String>();
args.add(arduinoPath.getAbsolutePath());
args.addAll(Arrays.asList(getBaseArgs()));
args.addAll(Arrays.asList(extraArgs));

System.out.println("Running: " + String.join(" ", args));

Process pr = rt.exec(args.toArray(new String[0]), null, wd);
if (output) {
IOUtils.copy(pr.getInputStream(), System.out);
IOUtils.copy(pr.getErrorStream(), System.out);
}
pr.waitFor();
if (success)
assertEquals(0, pr.exitValue());
return pr;
}

@Test
public void testCommandLineBuildWithRelativePath() throws Exception {
Runtime rt = Runtime.getRuntime();
File wd = new File(buildPath, "build/shared/examples/01.Basics/Blink/");
Process pr = rt
.exec(arduinoPath + " --board arduino:avr:uno --verify Blink.ino", null,
wd);
IOUtils.copy(pr.getInputStream(), System.out);
pr.waitFor();
assertEquals(0, pr.exitValue());
runArduino(true, true, wd, new String[] {
"--board", "arduino:avr:uno",
"--verify", "Blink.ino",
});
}

@Test
public void testCommandLinePreferencesSave() throws Exception {
Runtime rt = Runtime.getRuntime();
File prefFile = File.createTempFile("test_pref", ".txt");
prefFile.deleteOnExit();

Process pr = rt.exec(new String[] {
arduinoPath.getAbsolutePath(),
runArduino(true, true, null, new String[] {
"--save-prefs",
"--preferences-file", prefFile.getAbsolutePath(),
"--get-pref", // avoids starting the GUI
"--version", // avoids starting the GUI
});
IOUtils.copy(pr.getInputStream(), System.out);
IOUtils.copy(pr.getErrorStream(), System.out);
pr.waitFor();
assertEquals(0, pr.exitValue());

pr = rt.exec(new String[] {
arduinoPath.getAbsolutePath(),
runArduino(true, true, null, new String[] {
"--pref", "test_pref=xxx",
"--preferences-file", prefFile.getAbsolutePath(),
});
IOUtils.copy(pr.getInputStream(), System.out);
IOUtils.copy(pr.getErrorStream(), System.out);
pr.waitFor();
assertEquals(0, pr.exitValue());

PreferencesMap prefs = new PreferencesMap(prefFile);
assertNull("preference should not be saved", prefs.get("test_pref"));

pr = rt.exec(new String[] {
arduinoPath.getAbsolutePath(),
runArduino(true, true, null, new String[] {
"--pref", "test_pref=xxx",
"--preferences-file", prefFile.getAbsolutePath(),
"--save-prefs",
});
IOUtils.copy(pr.getInputStream(), System.out);
IOUtils.copy(pr.getErrorStream(), System.out);
pr.waitFor();
assertEquals(0, pr.exitValue());

prefs = new PreferencesMap(prefFile);
assertEquals("preference should be saved", "xxx", prefs.get("test_pref"));
}

@Test
public void testCommandLineVersion() throws Exception {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(new String[]{
arduinoPath.getAbsolutePath(),
Process pr = runArduino(false, true, null, new String[] {
"--version",
});
pr.waitFor();

Assertions.assertThat(pr.exitValue())
.as("Process will finish with exit code 0 in --version")
.isEqualTo(0);
Assertions.assertThat(new String(IOUtils.toByteArray(pr.getInputStream())))
.matches("Arduino: \\d+\\.\\d+\\.\\d+.*\r?\n");
}

@Test
public void testCommandLineMultipleAction() throws Exception {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(new String[]{
arduinoPath.getAbsolutePath(),
Process pr = runArduino(true, false, null, new String[] {
"--version",
"--verify",
});
pr.waitFor();

Assertions.assertThat(pr.exitValue())
.as("Multiple Action will be rejected")
Expand Down
2 changes: 1 addition & 1 deletion app/test/processing/app/DefaultTargetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void testDefaultTarget() throws Exception {
PreferencesData.set("board", "unreal_board");

// should not raise an exception
new Base(new String[0]);
createBase();

// skip test if no target platforms are available
Assume.assumeNotNull(BaseNoGui.getTargetPlatform());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
package processing.app;

import org.fest.swing.core.KeyPressInfo;
import org.fest.swing.core.matcher.DialogMatcher;
import org.fest.swing.finder.WindowFinder;
import org.fest.swing.fixture.DialogFixture;
import org.junit.Test;
Expand All @@ -39,6 +40,7 @@
import java.awt.event.KeyEvent;

import static org.junit.Assert.assertEquals;
import static processing.app.I18n.tr;

public class HittingEscapeOnCloseConfirmationDialogTest extends AbstractGUITest {

Expand All @@ -49,7 +51,8 @@ public void shouldJustCloseTheDialog() throws Exception {

window.close();

DialogFixture dialog = WindowFinder.findDialog(JDialog.class).using(window.robot);
DialogMatcher matcher = DialogMatcher.withTitle(tr("Close")).andShowing();
DialogFixture dialog = WindowFinder.findDialog(matcher).using(window.robot);
dialog.pressAndReleaseKey(KeyPressInfo.keyCode(KeyEvent.VK_ESCAPE));

EditorConsole console = (EditorConsole) window.scrollPane("console").component();
Expand Down
3 changes: 3 additions & 0 deletions arduino-core/src/processing/app/PreferencesData.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ static public void init(File file) throws Exception {
//ignore
}

// Start with a clean slate
prefs = new PreferencesMap();

// start by loading the defaults, in case something
// important was deleted from the user prefs
try {
Expand Down