Realm unit test with Robolectric and PowerMock generating zero % code coverage - unit-testing

I followed the instructions here:
https://github.com/robolectric/robolectric/wiki/Using-PowerMock
https://github.com/realm/realm-java/tree/master/examples/unitTestExample
to set up my realm unit tests. The tests all pass but when I try to generate the code coverage to push to SonarQube, the coverage report shows 0% coverage. When I execute the standard Android Studio code coverage (as described in the answer here: How to get code coverage using Android Studio?) it generates a report which shows 91% coverage. The problem with this approach however, is that it's an html report and there's no way to let it generate an xml report which can be used for SonarQube.
This is the code of the test class
#RunWith(RobolectricTestRunner.class)
#PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
#PrepareForTest({Realm.class, RealmConfiguration.class, RealmCore.class, RealmLog.class})
#SuppressStaticInitializationFor("io.realm.internal.Util")
#Config(constants = BuildConfig.class, manifest = "src/main/AndroidManifest.xml", sdk = 21)
public class DecisionTreeTest
{
#Captor
ArgumentCaptor<Realm.Transaction.Callback> realmCallbackCaptor;
// Robolectric, Using Power Mock https://github.com/robolectric/robolectric/wiki/Using-PowerMock
#Rule
public PowerMockRule rule = new PowerMockRule();
private Context mockContext;
private final byte[] fakeRealmKey = {
-122, -115, -113, -111, -105, -104, -101, -99, -94, -93, -90, -87,
-77, -74, -67, -66, -63, -61, -56, -53, -48, -47, -33, -31,
-30, -28, -22, -17, -5, -3, -1, 3, 8, 11, 17, 18,
21, 22, 27, 30, 40, 42, 51, 52, 53, 54, 57, 59,
61, 63, 67, 70, 74, 76, 78, 85, 90, 91, 103, 108,
113, 117, 119, 127
};
#Before
public void setUp() throws Exception
{
// Setup Realm to be mocked. The order of these matters
mockStatic(RealmCore.class);
mockStatic(RealmLog.class);
mockStatic(Realm.class);
mockStatic(RealmConfiguration.class);
this.mockContext = RuntimeEnvironment.application;
Whitebox.setInternalState(
Realm.class,
"applicationContext",
RuntimeEnvironment.application);
/*
Better solution would be just mock the RealmConfiguration.Builder class.
But it seems there is some problems for powermock to mock it (static inner class).
We just mock the RealmCore.loadLibrary(Context) which will be called by
RealmConfiguration.Builder's constructor.
*/
doNothing().when(RealmCore.class);
RealmCore.loadLibrary(any(Context.class));
}
#Test(expected = DecisionTreeException.class)
public void persistSurvey_DecisionTreeRealmNotEnabled_ThrowsException() throws Exception
{
DecisionTree decisionTree = createSimpleDecisionTree();
Survey survey = decisionTree.getSurveyFromResource(R.raw.survey);
decisionTree.persistSurvey(survey, null, null);
}
#Test(expected = DecisionTreeException.class)
public void persistSurvey_NullAsFirstParam_ThrowsException() throws Exception
{
DecisionTree decisionTree = createRealmDecisionTree();
decisionTree.persistSurvey(null, null, null);
}
#Test
public void persistSurvey_SurveyAsFirstParam_ThrowsException() throws Exception
{
final Realm mockRealm = mock(Realm.class);
when(Realm.getInstance(any(RealmConfiguration.class))).thenReturn(mockRealm);
org.mockito.stubbing.Answer<Void> executeAnswer = new org.mockito.stubbing.Answer<Void>()
{
#Override
public Void answer(InvocationOnMock invocation) throws Throwable
{
((Realm.Transaction) invocation.getArguments()[0]).execute(mockRealm);
return null;
}
};
doAnswer(executeAnswer)
.when(mockRealm)
.executeTransactionAsync(
any(Realm.Transaction.class),
any(Realm.Transaction.OnSuccess.class),
any(Realm.Transaction.OnError.class));
DecisionTree decisionTree = createRealmDecisionTree();
Survey survey = decisionTree.getSurveyFromResource(R.raw.survey);
decisionTree.persistSurvey(survey, null, null);
verify(mockRealm).executeTransactionAsync(
any(Realm.Transaction.class),
any(Realm.Transaction.OnSuccess.class),
any(Realm.Transaction.OnError.class));
verify(mockRealm).copyToRealmOrUpdate(any(Survey.class));
}
private DecisionTree createRealmDecisionTree()
{
return new DecisionTree.Builder()
.setContext(mockContext)
.setRealmKey(fakeRealmKey)
.setRealmEnabled(true)
.build();
}
private DecisionTree createSimpleDecisionTree()
{
return new DecisionTree.Builder()
.setContext(RuntimeEnvironment.application)
.build();
}
}
I think that the problem is the following line:
#Rule
public PowerMockRule rule = new PowerMockRule();
However, if I remove this line I get the following error although The #PrepareForTest line is unchanged.:
org.powermock.api.mockito.ClassNotPreparedException:
The class io.realm.internal.RealmCore not prepared for test.
To prepare this class, add class to the '#PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.

I guess you are using Jacoco to collect coverage. And PowerMock has a known issue with Jacoco/EclEmma. We're going to fix it in next release.
Update: PowerMock 1.6.6 has been released. It includes fix for JaCoCo offline instrumented code. So, now you may get code coverage with using JaCoCo maven plugin and offline instrumentation

Related

How do I load my Solana wallet using my private key file?

I'm attempting to use the private key I generated using the Solana command-line to create a wallet in JavaScript / Node.
I want to use the web3.Keypair.fromSeed() method.
Here are the steps I've take so far.
created a solana wallet : solana-keygen new -o keyfile.json
display what is in that file -- it's a 64 byte array (this is a test key so no worries that this is the private key
[237,158,92,107,132,192,1,57,8,20,213,108,29,227,37,8,3,105,196,244,8,221,184,199,62,253,98,131,33,165,165,215,14,7,46,23,221,242,240,226,94,79,161,31,192,163,13,25,106,53,34,215,83,124,162,156,8,97,194,180,213,179,33,68]
However, the call to fromSeed() only wants 32 bytes.
3. check the solana address so I know when everything is working properly :
> solana address -->
wm4MapPtFaUoSsyBJppVnChYMGvHzTeAL6BNZ5GmSqH
That's the public key
How do I call web3.Keypair.fromSeed() to load that private key and get my public address (aka public key)?
let web3 = require('#solana/web3.js');
let splToken = require('#solana/spl-token');
// load up the first 32 bytes of the 64 byte array that was in our keyfile.json
// Only need the first 32 bytes so I use slice() just to make sure it's the correct length
let firstWinPrivKey = [237,158,92,107,132,192,1,57,8,20,213,108,29,227,37,8,3,105,196,244,8,221,184,199,62,253,98,131,33,165,165,215,14,7,46,23,221,242,240,226,94,79,161,31,192,163,13,25,106,53,34,215,83,124,162,156,8,97,194,180,213,179,33,68]
.slice(0,32);
// print the length of the array so we know it is correct
// the fromSeed() method requires 32 bytes
console.log(firstWinPrivKey.length);
let firstWinWallet = web3.Keypair.fromSeed(Uint8Array.from(firstWinPrivKey));
console.log(firstWinWallet.secretKey);
console.log(firstWinWallet.publicKey.toString());
Notice that you have to cast the array to a Uint8Array (Uint8Array.from())
When we print out the secretKey, you'll see the same bytes you passed in.
And finally when we print out the publicKey you'll see that same value that we saw with the command line
> solana address
Now you can use the wallet in code.
Here's the final output from this short script:
32
Uint8Array(64) [
237, 158, 92, 107, 132, 192, 1, 57, 8, 20, 213,
108, 29, 227, 37, 8, 3, 105, 196, 244, 8, 221,
184, 199, 62, 253, 98, 131, 33, 165, 165, 215, 14,
7, 46, 23, 221, 242, 240, 226, 94, 79, 161, 31,
192, 163, 13, 25, 106, 53, 34, 215, 83, 124, 162,
156, 8, 97, 194, 180, 213, 179, 33, 68
]
wm4MapPtFaUoSsyBJppVnChYMGvHzTeAL6BNZ5GmSqH
If you want to use ".json" file, you can do something like this:
import Fs from "#supercharge/fs";
import { Connection, Keypair, LAMPORTS_PER_SOL } from "#solana/web3.js";
const decodedKey = new Uint8Array(
JSON.parse(
//replace with actual path from home dir. For example '.config/solana/devnet.json'
Fs.readFileSync(Fs.homeDir("path to key.json")).toString();
));
let keyPair = Keypair.fromSecretKey(decodedKey);
I use additional package https://www.npmjs.com/package/#supercharge/fs for working with files.
import { Keypair } from "#solana/web3.js";
import fs from "fs";
function loadKeypairFromFile(filename: string): Keypair {
const secret = JSON.parse(fs.readFileSync(filename).toString()) as number[];
const secretKey = Uint8Array.from(secret);
return Keypair.fromSecretKey(secretKey);
}

Ray - RLlib - Error with Custom env - continuous action space - DDPG - offline experience training?

Error while using offline experiences for DDPG. custom environment dimensions (action space and state space) seem to be inconsistent with what is expected in DDPG RLLIB trainer.
Ubuntu, Ray 0.7 version (latest ray), DDPG example, offline dataset.
Used sampler builder for offline dataset.
Estimated DQN with this experience data and it ran through. Changed environment action space to be continuous (Box(,1)) and DDPG did not work.
from ray.tune.registry import register_env
TRAIN_BATCH_SIZE = 512
class mmt_ctns_offline_logs(gym.Env):
def __init__(self):
self.action_space = Box(0,50,shape=(,1), dtype=np.float32) #one dimension action space, values range 0 to 50 max
self.observation_space = Box(-100000, 100000, shape=(,58), dtype=np.float32) #58 columns in state space
register_env("mmt_env_ctnaction", lambda config: mmt_ctns_offline_logs()) #register custom environment
#define the configuration. Some of these are defaults. But I have explicitely defined them for clarify (within my team)
config_dict = {"env": "mmt_env_ctnaction", "evaluation_num_episodes":50, "num_workers": 11, "sample_batch_size": 512,
"train_batch_size": TRAIN_BATCH_SIZE,
"input": "<experience_replay_folder>/",
"output": "<any_folder>", "gamma": 0.99,
"horizon": None,
"optimizer_class": "SyncReplayOptimizer",
"optimizer": {"prioritized_replay":True},
"actor_hiddens": [128, 64], "actor_hidden_activation": "relu",
"critic_hiddens": [64, 64], "critic_hidden_activation": "relu", "n_step": 1,
"target_network_update_freq": 500,
"input_evaluation": [],
"ignore_worker_failures":True, 'log_level': "DEBUG",
"buffer_size": 50000,
"prioritized_replay": True,
"prioritized_replay_alpha": 0.6,
"prioritized_replay_beta": 0.4,
"prioritized_replay_eps": 1e-6,
"compress_observations": False,
"lr": 1e-3,
"actor_loss_coeff": 0.1,
"critic_loss_coeff": 1.0,
"use_huber": False,
"huber_threshold": 1.0,
"l2_reg": 1e-6,
"grad_norm_clipping": True,
"learning_starts": 1500,
}
config = ddpg.DEFAULT_CONFIG.copy() #dqn.DEFAULT_CONFIG.copy()
for k,v in config_dict.items():
config[k] = v
config_ddpg = config
config_ddpg
run_experiments({
'NM_testing_DDPG_offpolicy_noIS': {
'run': 'DDPG',
'env': 'mmt_env_ctnaction',
'config': config_ddpg,
'local_dir': "/oxygen/narasimham/ray/tmp/mmt/mmt_user_27_DDPG/"
},
})
Expected results from DDPG iterations.
Actual - ERROR:-
ray.exceptions.RayTaskError: ray_DDPGTrainer:train() (pid=89635, host=ip-10-114-53-179)
File "/home/ubuntu/anaconda3/envs/tf_p36n/lib/python3.6/site-packages/ray/rllib/utils/tf_run_builder.py", line 49, in get
self.feed_dict, os.environ.get("TF_TIMELINE_DIR"))
File "/home/ubuntu/anaconda3/envs/tf_p36n/lib/python3.6/site-packages/ray/rllib/utils/tf_run_builder.py", line 91, in run_timeline
fetches = sess.run(ops, feed_dict=feed_dict)
File "/home/ubuntu/anaconda3/envs/tf_p36n/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 877, in run
run_metadata_ptr)
File "/home/ubuntu/anaconda3/envs/tf_p36n/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1076, in _run
str(subfeed_t.get_shape())))
ValueError: Cannot feed value of shape (512,) for Tensor 'default_policy/action:0', which has shape '(?, 1)'
During handling of the above exception, another exception occurred:
Try with action space definition as follows:
self.action_space = Box(0,50,shape=(1,), dtype=np.float32)

c++ enum as parameter in a function and calling the function in another file

I am making an engine in c++. Its nothing special yet and I am a beginner in c++ but I thought it would be a fun project to work on learn the skills I need later when I start working. I am making a function that takes user input and when that specific key is pressed it can execute the code you want like Input.GetKeyDown in unity. I have a problem and that is that I am trying to give an enum with all the keycodes for the keys as a parameter but it gives an error and I cant find a working sollution anywhere.
This is my code:
Functions.cpp
enum keyinputlist
{
a = 97, b = 98, c = 99, d = 100, e = 101,
f = 102, g = 103, h = 104, i = 105, j = 106, k = 107,
l = 108, m = 109, n = 110, o = 111, p = 112, q = 113,
r = 114, s = 115, t = 116, u = 117, v = 118,
w = 119, x = 120, y = 121, z = 122
};
bool Functions::test(keyinputlist List)
{
bool Success = CheckInput(List);
return Success;
}
Functions.h
class Functions
{
public:
Functions();
~Functions();
//Other public functions
bool test(keyinputlist List);
};
Main.cpp
int main()
{
Functions function;
if (function.test(a) != 0)
{
std::cout << "It worked!" << std::endl;
sleep_for(1.5s);
}
}
ErrorList:
E0020: identifier "a" is not found
E0020: identifier "keyinputlist" is not found
Someone answered this in a comment. Your problem is simple, the enum definition needs to go in Functions.h. You need to include Functions.h in both Main.cpp and Functions.cpp. Though because you aren't getting a lot more errors than you currently are I'm guessing you already do that.
In general, only code for non-template functions should go in a .cpp file. Type declarations and other similar things should probably live in a .h file.
The problem you're encountering is that because your enum is in a .cpp file and not included in Main.cpp, code in Main.cpp has no idea what you're talking about when you mention the enum type or any enum values. It hasn't seen any of that stuff, so it doesn't think it exists.
In general, the enum you have declared there seems like a bad idea. 'a' is already 97 on almost all platforms supporting C++ (excluding IBM mainframes). Defining a character encoding with an enum is going to lead you to write a lot of extra code later because it's cumbersome.
I have foudn the answer/problem.
I put in a instead of "class name"::a; that gave me the error and I put the enum in the header file and it works now.

How to write properly a groovy unit test with jUnit?

I am getting started with Groovy and I don't know how to write unit tests over my methods written on a class. For example:
One my methods on sample.groovy :
class sample {
def length = { list -> list.size() }
...
}
So, I have one class named sampleTest.groovy :
class sampleTest extends GroovyTestCase {
#Test
public void testLength() {
def result = length([2, 3, 8, 9, 0, 1, 5, 7])
assert result == 8
}
}
BTW, when I run this test, an error throws to me:
groovy.lang.MissingMethodException: No signature of method: sampleTest.length() is applicable for argument types: (java.util.ArrayList) values: [[2, 3, 8, 9, 0, 1, 5, 7]]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
...
length is a (non-static) property of the sample class. Because it's non-static, you need to evaluate it against a sample instance, e.g.
class sampleTest extends GroovyTestCase {
#Test
public void testLength() {
def result = new sample().length([2, 3, 8, 9, 0, 1, 5, 7])
assertEquals 8, result
}
}
Also, you should try to use the assertion methods provided by GroovyTestCase such as assertEquals, assertNotNull, assertTrue, rather than the assert keyword.
You should also capitalize your class names, e.g. Sample and SampleTest rather than sample and sampleTest.

Why getting the AssumptionViolatedException? Junit 4.8.2

I'm trying to make Junit tests. I want to start them by asking for a method in the CMS system. Because I'm testing plugins. The problem is that I get this exception and I don't know why. Naah I find that the problem could be that I'm using JUnit 4.8.2, but when I'm running the test in Eclipse everything worked fine. So I can't find the solution. Here is the error:
org.apache.velocity.exception.MethodInvocationException: Invocation of method
'getTest' in class nl.company.cms.three.viewtool.LoginViewTool threw exception
java.lang.NoClassDefFoundError: org/junit/internal/AssumptionViolatedException at
working/2a90929a-3fbf-43e9-9961-4a40279ec907_5c6e0bff-cfeb-44c6-86e2-
a0ba40e7b66c.field[line 1, column 15]
Here is the code of my class and test class:
Class that calls to start the Test:
public String getTest(){
Result r = org.junit.runner.JUnitCore.runClasses(MyTestClass.class);
if(r.getRunCount() > 0){
String s = "Failcount = " + r.getFailureCount() + " // " +
r.getRunCount() + " in " + r.getRunTime() + " ms";
System.out.println(r.getFailures().get(0).getTrace());
System.out.println("Runcount: "+r.getRunCount());
System.out.println("Runtime: "+r.getRunTime());
System.out.println("Ignore count: "+r.getIgnoreCount());
System.out.println("Failure count: "+ r.getFailureCount());
return s;
}
else{
return "Something ging kei verkeerd jonge!";
}
}
Test class:
public class MyTestClass {
#Test
public void testMultiply() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", 40, tester.multiply(10, 5));
}
#Test
public void testMultiply1() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", 50, tester.multiply(10, 5));
}
#Test
public void testMultiply2() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", "ASDF", tester.multiply(10, 5));
}
#Test
public void testMultiply3() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", 50, tester.multiply(10, 5));
}
#Test
public void testMultiply4() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", 47, tester.multiply(10, 5));
}
#Test
public void testMultiply5() {
CustomLoginViewTool tester = new CustomLoginViewTool();
assertEquals("Result", 50, tester.multiply(10, 5));
}
}
Assumptions are exceptions that JUnit will catch but which won't fail the test. These are for "this test only makes sense if" kind of questions. There is no point to fail Windows-path tests on a Linux system, for example - they can't succeed and failing them will give you an error that you can't fix without disabling the tests.
What I find odd is Velocity and JUnit in a single error message. Why is Velocity running JUnit?
The error means that the classpath isn't set up correctly. So you need to look into the classloader which is used to load the class which contains the method getTest()
The problem was that the CMS system uses JUnit 3.8.2 and the plugin needs JUnit 4.8.2. This caused the error because Java takes the newest version of JUnit and this has not the API of the AssumptionViolatedException.
That class implements a hamcrest class, so make sure you have the hamcrest-core jar on the classpath.