github.com/ur-technology/go-ur@v1.5.5/mobile/android_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains all the wrappers from the accounts package to support client side key 18 // management on mobile platforms. 19 20 package geth 21 22 import ( 23 "io/ioutil" 24 "os" 25 "os/exec" 26 "path/filepath" 27 "runtime" 28 "testing" 29 "time" 30 31 "github.com/ethereum/go-ethereum/internal/build" 32 ) 33 34 // androidTestClass is a Java class to do some lightweight tests against the Android 35 // bindings. The goal is not to test each individual functionality, rather just to 36 // catch breaking API and/or implementation changes. 37 const androidTestClass = ` 38 package go; 39 40 import android.test.InstrumentationTestCase; 41 import android.test.MoreAsserts; 42 43 import org.ethereum.geth.*; 44 45 public class AndroidTest extends InstrumentationTestCase { 46 public AndroidTest() {} 47 48 public void testAccountManagement() { 49 try { 50 AccountManager am = new AccountManager(getInstrumentation().getContext().getFilesDir() + "/keystore", Geth.LightScryptN, Geth.LightScryptP); 51 52 Account newAcc = am.newAccount("Creation password"); 53 byte[] jsonAcc = am.exportKey(newAcc, "Creation password", "Export password"); 54 55 am.deleteAccount(newAcc, "Creation password"); 56 Account impAcc = am.importKey(jsonAcc, "Export password", "Import password"); 57 } catch (Exception e) { 58 fail(e.toString()); 59 } 60 } 61 62 public void testInprocNode() { 63 Context ctx = new Context(); 64 65 try { 66 // Start up a new inprocess node 67 Node node = new Node(getInstrumentation().getContext().getFilesDir() + "/.ethereum", new NodeConfig()); 68 node.start(); 69 70 // Retrieve some data via function calls (we don't really care about the results) 71 NodeInfo info = node.getNodeInfo(); 72 info.getName(); 73 info.getListenerAddress(); 74 info.getProtocols(); 75 76 // Retrieve some data via the APIs (we don't really care about the results) 77 EthereumClient ec = node.getEthereumClient(); 78 ec.getBlockByNumber(ctx, -1).getNumber(); 79 80 NewHeadHandler handler = new NewHeadHandler() { 81 @Override public void onError(String error) {} 82 @Override public void onNewHead(final Header header) {} 83 }; 84 ec.subscribeNewHead(ctx, handler, 16); 85 } catch (Exception e) { 86 fail(e.toString()); 87 } 88 } 89 } 90 ` 91 92 // TestAndroid runs the Android java test class specified above. 93 // 94 // This requires the gradle command in PATH and the Android SDK whose path is available 95 // through ANDROID_HOME environment variable. To successfully run the tests, an Android 96 // device must also be available with debugging enabled. 97 // 98 // This method has been adapted from golang.org/x/mobile/bind/java/seq_test.go/runTest 99 func TestAndroid(t *testing.T) { 100 // Skip tests on Windows altogether 101 if runtime.GOOS == "windows" { 102 t.Skip("cannot test Android bindings on Windows, skipping") 103 } 104 // Make sure all the Android tools are installed 105 if _, err := exec.Command("which", "gradle").CombinedOutput(); err != nil { 106 t.Skip("command gradle not found, skipping") 107 } 108 if sdk := os.Getenv("ANDROID_HOME"); sdk == "" { 109 t.Skip("ANDROID_HOME environment var not set, skipping") 110 } 111 if _, err := exec.Command("which", "gomobile").CombinedOutput(); err != nil { 112 t.Log("gomobile missing, installing it...") 113 if _, err := exec.Command("go", "install", "golang.org/x/mobile/cmd/gomobile").CombinedOutput(); err != nil { 114 t.Fatalf("install failed: %v", err) 115 } 116 t.Log("initializing gomobile...") 117 start := time.Now() 118 if _, err := exec.Command("gomobile", "init").CombinedOutput(); err != nil { 119 t.Fatalf("initialization failed: %v", err) 120 } 121 t.Logf("initialization took %v", time.Since(start)) 122 } 123 // Create and switch to a temporary workspace 124 workspace, err := ioutil.TempDir("", "geth-android-") 125 if err != nil { 126 t.Fatalf("failed to create temporary workspace: %v", err) 127 } 128 defer os.RemoveAll(workspace) 129 130 pwd, err := os.Getwd() 131 if err != nil { 132 t.Fatalf("failed to get current working directory: %v", err) 133 } 134 if err := os.Chdir(workspace); err != nil { 135 t.Fatalf("failed to switch to temporary workspace: %v", err) 136 } 137 defer os.Chdir(pwd) 138 139 // Create the skeleton of the Android project 140 for _, dir := range []string{"src/main", "src/androidTest/java/org/ethereum/gethtest", "libs"} { 141 err = os.MkdirAll(dir, os.ModePerm) 142 if err != nil { 143 t.Fatal(err) 144 } 145 } 146 // Generate the mobile bindings for Geth and add the tester class 147 gobind := exec.Command("gomobile", "bind", "-javapkg", "org.ethereum", "github.com/ethereum/go-ethereum/mobile") 148 if output, err := gobind.CombinedOutput(); err != nil { 149 t.Logf("%s", output) 150 t.Fatalf("failed to run gomobile bind: %v", err) 151 } 152 build.CopyFile(filepath.Join("libs", "geth.aar"), "geth.aar", os.ModePerm) 153 154 if err = ioutil.WriteFile(filepath.Join("src", "androidTest", "java", "org", "ethereum", "gethtest", "AndroidTest.java"), []byte(androidTestClass), os.ModePerm); err != nil { 155 t.Fatalf("failed to write Android test class: %v", err) 156 } 157 // Finish creating the project and run the tests via gradle 158 if err = ioutil.WriteFile(filepath.Join("src", "main", "AndroidManifest.xml"), []byte(androidManifest), os.ModePerm); err != nil { 159 t.Fatalf("failed to write Android manifest: %v", err) 160 } 161 if err = ioutil.WriteFile("build.gradle", []byte(gradleConfig), os.ModePerm); err != nil { 162 t.Fatalf("failed to write gradle build file: %v", err) 163 } 164 if output, err := exec.Command("gradle", "connectedAndroidTest").CombinedOutput(); err != nil { 165 t.Logf("%s", output) 166 t.Errorf("failed to run gradle test: %v", err) 167 } 168 } 169 170 const androidManifest = `<?xml version="1.0" encoding="utf-8"?> 171 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 172 package="org.ethereum.gethtest" 173 android:versionCode="1" 174 android:versionName="1.0"> 175 176 <uses-permission android:name="android.permission.INTERNET" /> 177 </manifest>` 178 179 const gradleConfig = `buildscript { 180 repositories { 181 jcenter() 182 } 183 dependencies { 184 classpath 'com.android.tools.build:gradle:1.5.0' 185 } 186 } 187 allprojects { 188 repositories { jcenter() } 189 } 190 apply plugin: 'com.android.library' 191 android { 192 compileSdkVersion 'android-19' 193 buildToolsVersion '21.1.2' 194 defaultConfig { minSdkVersion 15 } 195 } 196 repositories { 197 flatDir { dirs 'libs' } 198 } 199 dependencies { 200 compile 'com.android.support:appcompat-v7:19.0.0' 201 compile(name: "geth", ext: "aar") 202 } 203 `