diff options
author | Mark Spruiell <mes@zeroc.com> | 2017-06-06 15:51:30 -0700 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2017-06-06 15:51:30 -0700 |
commit | e99e1388d3b45e2e93888bca29ed540f245e2166 (patch) | |
tree | 8685d4a3a0ca84f257e2b326965609da554a60ba /java-compat/android/test/controller/src | |
parent | Fixed Ice/operations build failure with ARC target of iOS controller project (diff) | |
download | ice-e99e1388d3b45e2e93888bca29ed540f245e2166.tar.bz2 ice-e99e1388d3b45e2e93888bca29ed540f245e2166.tar.xz ice-e99e1388d3b45e2e93888bca29ed540f245e2166.zip |
ICE-7903 - move android tests
Diffstat (limited to 'java-compat/android/test/controller/src')
7 files changed, 772 insertions, 0 deletions
diff --git a/java-compat/android/test/controller/src/main/AndroidManifest.xml b/java-compat/android/test/controller/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..e1e041d8acd --- /dev/null +++ b/java-compat/android/test/controller/src/main/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.zeroc.testcontroller" + android:versionCode="1" + android:versionName="1.0.0"> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> + + <!-- + http://developer.android.com/guide/topics/manifest/uses-sdk-element.html + --> + <application android:icon="@raw/icon" android:label="@string/app_name" android:name="ControllerApp" + android:allowBackup="false"> + <activity android:name="ControllerActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> +</application> +</manifest> diff --git a/java-compat/android/test/controller/src/main/assets/.gitignore b/java-compat/android/test/controller/src/main/assets/.gitignore new file mode 100644 index 00000000000..2cbf86bc394 --- /dev/null +++ b/java-compat/android/test/controller/src/main/assets/.gitignore @@ -0,0 +1 @@ +*.dex diff --git a/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java b/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java new file mode 100644 index 00000000000..f8e58769986 --- /dev/null +++ b/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java @@ -0,0 +1,88 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package com.zeroc.testcontroller; + +import java.util.LinkedList; +import android.app.*; +import android.content.Context; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.widget.*; +import android.view.View; + +public class ControllerActivity extends ListActivity +{ + private WifiManager _wifiManager; + private WifiManager.MulticastLock _lock; + private LinkedList<String> _output = new LinkedList<String>(); + private ArrayAdapter<String> _outputAdapter; + private ArrayAdapter<String> _ipv4Adapter; + private ArrayAdapter<String> _ipv6Adapter; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + _wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE); + _lock = _wifiManager.createMulticastLock("com.zeroc.testcontroller"); + _lock.acquire(); + + _outputAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, _output); + setListAdapter(_outputAdapter); + + final ControllerApp app = (ControllerApp)getApplication(); + final java.util.List<String> ipv4Addresses = app.getAddresses(false); + _ipv4Adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, ipv4Addresses); + Spinner s = (Spinner)findViewById(R.id.ipv4); + s.setAdapter(_ipv4Adapter); + s.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() + { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) + { + app.setIpv4Address(ipv4Addresses.get((int)id)); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) + { + } + }); + s.setSelection(0); + + final java.util.List<String> ipv6Addresses = app.getAddresses(true); + _ipv6Adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, ipv6Addresses); + s = (Spinner)findViewById(R.id.ipv6); + s.setAdapter(_ipv6Adapter); + s.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() + { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) + { + app.setIpv6Address(ipv6Addresses.get((int)id)); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) + { + } + }); + s.setSelection(0); + app.startController(this); + } + + public synchronized void println(String data) + { + _output.add(data); + _outputAdapter.notifyDataSetChanged(); + } +} diff --git a/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java b/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java new file mode 100644 index 00000000000..13539166c86 --- /dev/null +++ b/java-compat/android/test/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java @@ -0,0 +1,601 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package com.zeroc.testcontroller; + +import java.io.*; +import java.util.*; + +import Ice.Logger; +import Ice.Communicator; + +import dalvik.system.DexClassLoader; + +import android.content.Context; +import android.os.Build; +import android.util.Log; +import android.app.Application; + +import Test.Common.ProcessControllerRegistryPrxHelper; +import Test.Common.ProcessControllerRegistryPrx; +import Test.Common.ProcessControllerPrx; +import Test.Common.ProcessControllerPrxHelper; +import test.Util.Application.CommunicatorListener; + +public class ControllerApp extends Application +{ + private final String TAG = "ControllerApp"; + private ControllerHelper _helper; + private ControllerActivity _controller; + private java.util.Map<String, ClassLoader> _classLoaders = new java.util.HashMap<String, ClassLoader>(); + private String _ipv4Address; + private String _ipv6Address; + + private ClassLoader getDEXClassLoader(String classDir, ClassLoader parent) throws IOException + { + ClassLoader classLoader = _classLoaders.get(classDir); + if(classLoader == null) + { + if(parent == null) + { + parent = getClassLoader(); + } + + File dexInternalStoragePath = new java.io.File(getDir("dex", Context.MODE_PRIVATE), classDir); + BufferedInputStream bis = new BufferedInputStream(getAssets().open(classDir)); + OutputStream dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath)); + final int sz = 8 * 1024; + byte[] buf = new byte[sz]; + int len; + while((len = bis.read(buf, 0, sz)) > 0) + { + dexWriter.write(buf, 0, len); + } + dexWriter.close(); + bis.close(); + + // Internal storage where the DexClassLoader writes the optimized dex file to + final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE); + + classLoader = new DexClassLoader( + dexInternalStoragePath.getAbsolutePath(), + optimizedDexOutputPath.getAbsolutePath(), + null, + parent); + _classLoaders.put(classDir, classLoader); + } + return classLoader; + } + + static private class TestSuiteBundle + { + @SuppressWarnings("unchecked") + TestSuiteBundle(String name, ClassLoader loader) + { + _loader = loader; + try + { + _class = (Class<? extends test.Util.Application>)_loader.loadClass(name); + } + catch(ClassNotFoundException e) + { + } + } + + test.Util.Application newInstance() + throws IllegalAccessException, InstantiationException + { + if(_class == null) + { + return null; + } + return _class.newInstance(); + } + + ClassLoader getClassLoader() + { + return _loader; + } + + private String _name; + private ClassLoader _loader; + private Class<? extends test.Util.Application> _class; + } + + class AndroidLogger implements Ice.Logger + { + private final String _prefix; + + AndroidLogger(String prefix) + { + _prefix = prefix; + } + + @Override + public void print(String message) + { + Log.d(TAG, message); + } + + @Override + public void trace(String category, String message) + { + Log.v(category, message); + } + + @Override + public void warning(String message) + { + Log.w(TAG, message); + } + + @Override + public void error(String message) + { + Log.e(TAG, message); + } + + @Override + public String getPrefix() + { + return _prefix; + } + + @Override + public Logger cloneWithPrefix(String s) + { + return new AndroidLogger(s); + } + } + + @Override + public void onCreate() + { + super.onCreate(); + Ice.Util.setProcessLogger(new AndroidLogger("")); + } + + synchronized public void setIpv4Address(String address) + { + _ipv4Address = address; + } + + synchronized public void setIpv6Address(String address) + { + int i = address.indexOf("%"); + _ipv6Address = i == -1 ? address : address.substring(i); + } + + public List<String> getAddresses(boolean ipv6) + { + List<String> addresses = new java.util.ArrayList<String>(); + try + { + java.util.Enumeration<java.net.NetworkInterface> ifaces = java.net.NetworkInterface.getNetworkInterfaces(); + while(ifaces.hasMoreElements()) + { + java.net.NetworkInterface iface = ifaces.nextElement(); + java.util.Enumeration<java.net.InetAddress> addrs = iface.getInetAddresses(); + while (addrs.hasMoreElements()) + { + java.net.InetAddress addr = addrs.nextElement(); + if((ipv6 && addr instanceof java.net.Inet6Address) || + (!ipv6 && !(addr instanceof java.net.Inet6Address))) + { + addresses.add(addr.getHostAddress()); + } + } + } + } + catch(java.net.SocketException ex) + { + } + return addresses; + } + + public synchronized void startController(ControllerActivity controller) + { + if(_helper == null) + { + _controller = controller; + _helper = new ControllerHelper(); + } + else + { + _controller = controller; + } + } + + public synchronized void println(final String data) + { + _controller.runOnUiThread(new Runnable() + { + @Override + public void run() + { + synchronized(ControllerApp.this) + { + _controller.println(data); + } + } + }); + } + + public static boolean isEmulator() + { + return Build.FINGERPRINT.startsWith("generic") || + Build.FINGERPRINT.startsWith("unknown") || + Build.MODEL.contains("google_sdk") || + Build.MODEL.contains("Emulator") || + Build.MODEL.contains("Android SDK built for x86") || + Build.MANUFACTURER.contains("Genymotion") || + (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || + Build.PRODUCT.equals("google_sdk"); + } + + class ControllerHelper + { + public ControllerHelper() + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.ThreadPool.Server.SizeMax", "10"); + initData.properties.setProperty("ControllerAdapter.Endpoints", "tcp"); + initData.properties.setProperty("ControllerAdapter.AdapterId", java.util.UUID.randomUUID().toString()); + initData.properties.setProperty("Ice.Override.ConnectTimeout", "1000"); + if(!isEmulator()) + { + initData.properties.setProperty("Ice.Plugin.IceDiscovery", "IceDiscovery.PluginFactory"); + initData.properties.setProperty("IceDiscovery.DomainId", "TestController"); + } + _communicator = Ice.Util.initialize(initData); + Ice.ObjectAdapter adapter = _communicator.createObjectAdapter("ControllerAdapter"); + ProcessControllerPrx processController = ProcessControllerPrxHelper.uncheckedCast( + adapter.add(new ProcessControllerI(), Ice.Util.stringToIdentity("Android/ProcessController"))); + adapter.activate(); + if(isEmulator()) + { + ProcessControllerRegistryPrx registry = ProcessControllerRegistryPrxHelper.uncheckedCast( + _communicator.stringToProxy("Util/ProcessControllerRegistry:tcp -h 10.0.2.2 -p 15001")); + registerProcessController(adapter, registry, processController); + } + println("Android/ProcessController"); + } + + public void + registerProcessController(final Ice.ObjectAdapter adapter, + final ProcessControllerRegistryPrx registry, + final ProcessControllerPrx processController) + { + registry.begin_ice_ping( + new Ice.Callback() + { + public void completed(Ice.AsyncResult r) + { + try + { + registry.end_ice_ping(r); + Ice.Connection connection = registry.ice_getCachedConnection(); + connection.setAdapter(adapter); + connection.setACM(new Ice.IntOptional(5), + new Ice.Optional<Ice.ACMClose>(Ice.ACMClose.CloseOff), + new Ice.Optional<Ice.ACMHeartbeat>(Ice.ACMHeartbeat.HeartbeatAlways)); + + connection.setCloseCallback(new Ice.CloseCallback() + { + @Override + public void closed(Ice.Connection con) + { + println("connection with process controller registry closed"); + while(true) + { + try + { + Thread.sleep(500); + break; + } + catch(InterruptedException e) + { + } + } + registerProcessController(adapter, registry, processController); + } + }); + + registry.begin_setProcessController(processController, + new Ice.Callback() + { + public void completed(Ice.AsyncResult r) + { + try + { + registry.end_setProcessController(r); + } + catch(Ice.Exception ex) + { + handleException(ex, adapter, registry, processController); + } + } + }); + } + catch(Ice.Exception ex) + { + handleException(ex, adapter, registry, processController); + } + } + }); + } + + public void handleException(Throwable ex, + final Ice.ObjectAdapter adapter, + final ProcessControllerRegistryPrx registry, + final ProcessControllerPrx processController) + { + if(ex instanceof Ice.ConnectFailedException || ex instanceof Ice.TimeoutException) + { + while (true) + { + try + { + Thread.sleep(500); + break; + } + catch(InterruptedException e) + { + } + } + registerProcessController(adapter, registry, processController); + } + else + { + println(ex.toString()); + } + } + + public void destroy() + { + _communicator.destroy(); + } + + private ProcessControllerRegistryPrx _registry; + private Ice.Communicator _communicator; + } + + class MainHelperI extends Thread implements test.Util.Application.ServerReadyListener + { + public MainHelperI(TestSuiteBundle bundle, String[] args, String exe) + { + _bundle = bundle; + _args = args; + } + + public void run() + { + try + { + _app = _bundle.newInstance(); + _app.setClassLoader(_bundle.getClassLoader()); + _app.setCommunicatorListener(new CommunicatorListener() + { + public void communicatorInitialized(Communicator communicator) + { + if(communicator.getProperties().getProperty("Ice.Plugin.IceSSL").equals("IceSSL.PluginFactory")) + { + IceSSL.Plugin plugin = (IceSSL.Plugin)communicator.getPluginManager().getPlugin("IceSSL"); + String keystore = communicator.getProperties().getProperty("IceSSL.Keystore"); + communicator.getProperties().setProperty("IceSSL.Keystore", ""); + java.io.InputStream certs = getResources().openRawResource( + keystore.equals("client.bks") ? R.raw.client : R.raw.server); + plugin.setKeystoreStream(certs); + plugin.setTruststoreStream(certs); + communicator.getPluginManager().initializePlugins(); + } + } + }); + _app.setWriter(new Writer() + { + @Override + public void close() throws IOException + { + } + + @Override + public void flush() throws IOException + { + } + + @Override + public void write(char[] buf, int offset, int count) + throws IOException + { + _out.append(buf, offset, count); + } + }); + _app.setServerReadyListener(this); + + int status = _app.main(_exe, _args); + synchronized(this) + { + _status = status; + _completed = true; + notifyAll(); + } + } + catch(Exception ex) + { + _out.append(ex.toString()); + synchronized(this) + { + _status = -1; + _completed = true; + notifyAll(); + } + } + } + + public void shutdown() + { + if(_app != null) + { + _app.stop(); + } + } + + public String getOutput() + { + return _out.toString(); + } + + synchronized private void completed(int status) + { + _completed = true; + _status = status; + notifyAll(); + } + + synchronized public void serverReady() + { + _ready = true; + notifyAll(); + } + + synchronized private void waitReady(int timeout) + throws Test.Common.ProcessFailedException + { + long now = IceInternal.Time.currentMonotonicTimeMillis(); + while(!_ready && !_completed) + { + try + { + wait(timeout * 1000); + if(IceInternal.Time.currentMonotonicTimeMillis() - now > timeout * 1000) + { + throw new Test.Common.ProcessFailedException("timed out waiting for the process to be ready"); + } + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_completed && _status != 0) + { + throw new Test.Common.ProcessFailedException(_out.toString()); + } + } + + synchronized private int waitSuccess(int timeout) + throws Test.Common.ProcessFailedException + { + long now = IceInternal.Time.currentMonotonicTimeMillis(); + while(!_completed) + { + try + { + wait(timeout * 1000); + if(IceInternal.Time.currentMonotonicTimeMillis() - now > timeout * 1000) + { + throw new Test.Common.ProcessFailedException("timed out waiting for the process to be ready"); + } + } + catch(java.lang.InterruptedException ex) + { + } + } + return _status; + } + + private TestSuiteBundle _bundle; + private String[] _args; + private String _exe; + private test.Util.Application _app; + private boolean _ready = false; + private boolean _completed = false; + private int _status = 0; + private final StringBuffer _out = new StringBuffer(); + } + + class ProcessControllerI extends Test.Common._ProcessControllerDisp + { + public Test.Common.ProcessPrx start(final String testsuite, final String exe, String[] args, Ice.Current current) + throws Test.Common.ProcessFailedException + { + println("starting " + testsuite + " " + exe + "... "); + String className = "test." + testsuite.replace("/", ".") + "." + exe.substring(0, 1).toUpperCase() + exe.substring(1); + String dexFile = "test_" + testsuite.replace("/", "_") + ".dex"; + try + { + TestSuiteBundle bundle = new TestSuiteBundle(className, getDEXClassLoader(dexFile, null)); + MainHelperI mainHelper = new MainHelperI(bundle, args, exe); + mainHelper.start(); + return Test.Common.ProcessPrxHelper.uncheckedCast(current.adapter.addWithUUID(new ProcessI(mainHelper))); + } + catch(IOException ex) + { + throw new Test.Common.ProcessFailedException( + "testsuite `" + testsuite + "' exe ` " + exe + "' start failed:\n" + ex.toString()); + } + } + + public String getHost(String protocol, boolean ipv6, Ice.Current current) + { + if(isEmulator()) + { + return "127.0.0.1"; + } + else + { + synchronized(ControllerApp.this) + { + return ipv6 ? _ipv6Address : _ipv4Address; + } + } + } + } + + class ProcessI extends Test.Common._ProcessDisp + { + public ProcessI(MainHelperI helper) + { + _helper = helper; + } + + public void waitReady(int timeout, Ice.Current current) + throws Test.Common.ProcessFailedException + { + _helper.waitReady(timeout); + } + + public int waitSuccess(int timeout, Ice.Current current) + throws Test.Common.ProcessFailedException + { + return _helper.waitSuccess(timeout); + } + + public String terminate(Ice.Current current) + { + _helper.shutdown(); + current.adapter.remove(current.id); + while(true) + { + try + { + _helper.join(); + break; + } + catch(InterruptedException ex) + { + } + } + return _helper.getOutput(); + } + + private MainHelperI _helper; + } +} diff --git a/java-compat/android/test/controller/src/main/res/layout/main.xml b/java-compat/android/test/controller/src/main/res/layout/main.xml new file mode 100644 index 00000000000..df4c8db98c7 --- /dev/null +++ b/java-compat/android/test/controller/src/main/res/layout/main.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingBottom="5dip"> + <TextView + android:layout_width="5dip" + android:layout_weight="25" + android:layout_height="wrap_content" + android:text="IPv4" + android:layout_gravity="center_vertical"/> + + <Spinner + android:id="@+id/ipv4" + android:layout_width="5dip" + android:layout_weight="75" + android:layout_height="wrap_content" + android:drawSelectorOnTop="false"/> + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingBottom="5dip"> + <TextView + android:layout_width="0dip" + android:layout_weight="25" + android:layout_height="wrap_content" + android:text="IPv6" + android:layout_gravity="center_vertical"/> + + <Spinner + android:id="@+id/ipv6" + android:layout_width="0dip" + android:layout_weight="75" + android:layout_height="wrap_content" + android:drawSelectorOnTop="false"/> + </LinearLayout> + + <ListView + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:stackFromBottom="true" + android:transcriptMode="alwaysScroll"/> +</LinearLayout> diff --git a/java-compat/android/test/controller/src/main/res/raw/icon.png b/java-compat/android/test/controller/src/main/res/raw/icon.png Binary files differnew file mode 100644 index 00000000000..75024841d32 --- /dev/null +++ b/java-compat/android/test/controller/src/main/res/raw/icon.png diff --git a/java-compat/android/test/controller/src/main/res/values/strings.xml b/java-compat/android/test/controller/src/main/res/values/strings.xml new file mode 100644 index 00000000000..46a3b776b80 --- /dev/null +++ b/java-compat/android/test/controller/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Test Controller</string> +</resources> |