forcedotcom / ApexUnit

ApexUnit is a powerful continuous integration tool for the Force.com platform
BSD 3-Clause "New" or "Revised" License
71 stars 51 forks source link

Exception thrown while trying to create Partner Connection!!!Failed to get next element #29

Closed TedHusted closed 8 years ago

TedHusted commented 8 years ago

[Moving from email thread to an issue]

I'm having a spot of bother getting ApexUnit up and running.

Any insight you can provide would be appreciated because I'd very much like to get this tool up and running for us. We develop three managed packages for diverse customers with complex implementations, and being sure all the test pass with optimal coverage is crucial for us.

I'm able to connect with the curl command

curl -v https://login.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=3MVG98XJQQAccJQcC7AAOFrxPf5wo7oCP1h83CjrbS9dKlmFDx_e7xSB5XaN7vBR9IO2uPQID_9LnisG6HRmg" -d "client_secret=1103520132783667035" -d "username=admin@nc.branch" -d "password=$password"

and it returns a token

{"access_token":"00DG00000005KL8!AQwAQJ6uAyNbyTJ3o9PBVZPRZN9uL5L3OUdz7ASSmXW01acvelJS170Kyg9.db7SV.m87hb9wpv8ex1xrFFZxytKy1Yi6rUP","instance_url":"https://na11.salesforce.com","id":"https://login.salesforce.com/id/00DG00000005KL8MAM/005G0000005IPdoIAG","token_type":"Bearer","issued_at":"1456821243980","signature":"N74stPAnX2fj0mHv2kAkwxliPDeftn67HRtw4qH8xt4="}

when I try the Maven command against a fresh checkout of ApexUnit

/opt/apache-maven/bin/mvn compile exec:java -Dexec.mainClass="com.sforce.cd.apexUnit.ApexUnitRunner" -Dexec.args="-org.login.url https://login.salesforce.com/services/oauth2/token -org.client.id 3MVG98XJQQAccJQcC7AAOFrxPf5wo7oCP1h83CjrbS9dKlmFDx_e7xSB5XaN7vBR9IO2uPQID_9LnisG6HRmg -org.client.secret 1103520132783667035 -org.username admin@nc.branch -org.password $password -regex.for.selecting.source.classes.for.code.coverage.computation Action -regex.for.selecting.test.classes.to.execute ActionTest"

the system presents


[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building ApexUnit 2.3.2 [INFO] ------------------------------------------------------------------------ [WARNING] The artifact org.apache.commons:commons-io:jar:1.3.2 has been relocated to commons-io:commons-io:jar:1.3.2 [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ ApexUnit-core --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 7 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ ApexUnit-core --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) > validate @ ApexUnit-core >>> [INFO] [INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) < validate @ ApexUnit-core <<< [INFO] [INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ ApexUnit-core --- [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.ApexUnitRunner - #################################### Processing the Apex test classes specified by the user #################################### [com.sforce.cd.apexUnit.ApexUnitRunner.main()] ERROR com.sforce.cd.apexUnit.ApexUnitUtils - Exception thrown while trying to create Partner Connection!!!Failed to get next element [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.ApexUnitUtils - Shutting down ApexUnit java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:1365) at com.sforce.cd.apexUnit.ApexUnitUtils.shutDownWithErrMsg(ApexUnitUtils.java:68) at com.sforce.cd.apexUnit.ApexUnitUtils.shutDownWithDebugLog(ApexUnitUtils.java:53) at com.sforce.cd.apexUnit.client.connection.ConnectionHandler.createConnection(ConnectionHandler.java:130) at com.sforce.cd.apexUnit.client.connection.ConnectionHandler.getConnection(ConnectionHandler.java:200) at com.sforce.cd.apexUnit.client.testEngine.TestExecutor.testExecutionFlow(TestExecutor.java:50) at com.sforce.cd.apexUnit.ApexUnitRunner.main(ApexUnitRunner.java:74) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297) at java.lang.Thread.run(Thread.java:745)


The Action and ActionTest classes exist in the target org. For debugging purposes, I'm not trying a wildcard regex but passing two actual class names.

The org is a Developer Edition branch pilot org with a prefix enabled. I've also tried adding the prefix reference with no joy.

I can start over and try it with a scratch org first but I thought you might have a ready answer for this particular error message.

Maven 3.3.9 is installed at /opt/apache-maven and the java -version is

java version "1.7.0_91" OpenJDK Runtime Environment (amzn-2.6.2.2.63.amzn1-x86_64 u91-b00) OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)

-Ted.

---------- Forwarded message ---------- From: Adarsh Ramakrishna adarsh.ramakrishna@salesforce.com Date: Tue, Mar 1, 2016 at 5:07 PM Subject: Re: ApexUnit - Exception thrown while trying to create Partner Connection!!!Failed to get next element To: Ted Husted NU thusted@nimbleuser.com Cc: IT-CD it-cd@salesforce.com

Hi Ted, Welcome to ApexUnit community! Thanks for reaching out to us. Do you mind logging this issue on github for tracking purpose? Our suggestion is: Please try using -org.login.url https://login.salesforce.com/ over to using -org.login.url https://login.salesforce.com/services/oauth2/token in the maven command. Let us know how it goes.

Also, The curl command is for verifying Tooling API connection for code coverage computation and has no impact on the partner connection handling which is used to execute the tests. I am glad that you verified it, code coverage computation should work for you with your current setup. Thanks, Adarsh

TedHusted commented 8 years ago

Changing the login url to -org.login.url https://login.salesforce.com

did help, though I'm up against another error now.


[com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.client.utils.ApexClassFetcherUtils - Using regex(es): ActionTest to fetch apex classes [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.client.utils.ApexClassFetcherUtils - Using regex: "ActionTest" to fetch apex classes [com.sforce.cd.apexUnit.ApexUnitRunner.main()] ERROR com.sforce.cd.apexUnit.ApexUnitUtils - No/Invalid test classes mentioned in manifest file and/or regex pattern for ApexTestPrefix didn't return any test class names from the org


It's a branch pilot org, and so there is a managed package prefix associated with the org.

I tried with and without the prefix. I also tried escaping the "." in the prefix, which presented a different error


[com.sforce.cd.apexUnit.ApexUnitRunner.main()] ERROR com.sforce.cd.apexUnit.ApexUnitUtils - Connection Exception encountered when trying to query : SELECT Id , Name FROM ApexClass WHERE NamespacePrefix =null AND Name like 'NC.ActionTest%'


Have people been using ApexUnit successfully with packaging orgs?

How is the prefix reference handled?

-Ted.

tfuda commented 8 years ago

Hi Ted,

I opened an issue about this awhile back and a solution was implemented that should allow you to specify the namespace as part of your regex. If your namespace is "NC", then you should be able to specify the regex as NC.ActionTest*. Please see the commentary on this pull request: https://github.com/forcedotcom/ApexUnit/pull/14 for some background.

TedHusted commented 8 years ago

Hmmm, that's what I'm doing with a fresh checkout.


/opt/apache-maven/bin/mvn compile exec:java -Dexec.mainClass="com.sforce.cd.apexUnit.ApexUnitRunner" -Dexec.args="-org.login.url https://login.salesforce.com -org.client.id 3MVG98XJQQAccJQcC7AAOFrxPf5wo7oCP1h83CjrbS9dKlmFDx_e7xSB5XaN7vBR9IO2uPQID_9LnisG6HRmg -org.client.secret 1103520132783667035 -org.username admin@nc.branch -org.password $password -regex.for.selecting.source.classes.for.code.coverage.computation NC.Action -regex.for.selecting.test.classes.to.execute NC.ActionTest" [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building ApexUnit 2.3.2 [INFO] ------------------------------------------------------------------------ [WARNING] The artifact org.apache.commons:commons-io:jar:1.3.2 has been relocated to commons-io:commons-io:jar:1.3.2 [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ ApexUnit-core --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 7 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ ApexUnit-core --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) > validate @ ApexUnit-core >>> [INFO] [INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) < validate @ ApexUnit-core <<< [INFO] [INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ ApexUnit-core --- [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.ApexUnitRunner - #################################### Processing the Apex test classes specified by the user #################################### [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.client.utils.ApexClassFetcherUtils - Using regex(es): NC.ActionTest to fetch apex classes [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.client.utils.ApexClassFetcherUtils - Using regex: "NC.ActionTest" to fetch apex classes [com.sforce.cd.apexUnit.ApexUnitRunner.main()] ERROR com.sforce.cd.apexUnit.ApexUnitUtils - No/Invalid test classes mentioned in manifest file and/or regex pattern for ApexTestPrefix didn't return any test class names from the org [com.sforce.cd.apexUnit.ApexUnitRunner.main()] INFO com.sforce.cd.apexUnit.ApexUnitUtils - Shutting down ApexUnit java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:1365) at com.sforce.cd.apexUnit.ApexUnitUtils.shutDownWithErrMsg(ApexUnitUtils.java:68) at com.sforce.cd.apexUnit.client.utils.ApexClassFetcherUtils.constructTestClassesArray(ApexClassFetcherUtils.java:100) at com.sforce.cd.apexUnit.client.testEngine.TestExecutor.testExecutionFlow(TestExecutor.java:54) at com.sforce.cd.apexUnit.ApexUnitRunner.main(ApexUnitRunner.java:74) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297) at java.lang.Thread.run(Thread.java:745)


And the classes do exist.

action


Any thoughts? I could try a manifest, if that might help.

Or even some other org to see if I can get this running someplace.

tfuda commented 8 years ago

Hmm... that certainly looks like the correct pattern. I would have expected that to work. I can try the pattern with a namespace prefix in one of my packager orgs tommorrow to see if I can get it to work.

tfuda commented 8 years ago

Ted, I concur with your findings. This appears to be broken right now. It looks like the code that splits the "regex" on . is absent from ApexClassFetcherUtils.fetchApexClassesBasedOnRegex.

private static String[] fetchApexClassesBasedOnRegex(PartnerConnection connection, String[] classesAsArray,
            String regex, Boolean includeTriggers) {
        if (regex != null && !regex.equals(" ")) {
            LOG.info("Using regex: \"" + regex + "\" to fetch apex classes");
            // construct the query
            String namespace = null;
            String soql = QueryConstructor.generateQueryToFetchApexClassesBasedOnRegex(namespace, regex);
            // fire the query using WSC and fetch the results
            String[] classesAsArrayUsingWSC = constructClassIdArrayUsingWSC(connection, soql);
            // if both manifest file and testClass regex expression is provided
            // as command line option, combine the results

            Set<String> uniqueSetOfClasses = new HashSet<String>();
            ArrayList<String> duplicateList = new ArrayList<String>();
            // eliminate duplicates from the given class Ids
            // (just in case duplicates still exist in the class array passed
            // from the calling method)
            if (classesAsArray != null && classesAsArray.length > 0) {
                for (int i = 0; i < classesAsArray.length; i++) {
                    if (!uniqueSetOfClasses.add(classesAsArray[i])) {
                        duplicateList.add(classesAsArray[i]);
                    }
                }
            }
            // eliminate duplicates from the classes fetched using the prefix
            if (classesAsArrayUsingWSC != null && classesAsArrayUsingWSC.length > 0) {
                for (int i = 0; i < classesAsArrayUsingWSC.length; i++) {
                    if (!uniqueSetOfClasses.add(classesAsArrayUsingWSC[i])) {
                        duplicateList.add(classesAsArrayUsingWSC[i]);
                    }
                }
            }

            //if include triggers, add triggers to duplicate list as Triggers cannot be tested on force.com
            if(includeTriggers){
                String soqlForTrigger = QueryConstructor.generateQueryToFetchApexTriggersBasedOnRegex(namespace, regex);
                String[] triggersAsArrayUsingWSC = constructClassIdArrayUsingWSC(connection, soqlForTrigger);

                if (triggersAsArrayUsingWSC != null && triggersAsArrayUsingWSC.length > 0) {
                    for (int i = 0; i < triggersAsArrayUsingWSC.length; i++) {
                        if (!uniqueSetOfClasses.add(triggersAsArrayUsingWSC[i])) {
                            duplicateList.add(triggersAsArrayUsingWSC[i]);
                        }
                    }
                }
            }

            // eliminate duplicates from the triggers fetched using the prefix

            String[] uniqueClassesAsArray = uniqueSetOfClasses.toArray(new String[uniqueSetOfClasses.size()]);

            // log the duplicate classes/triggers found by querying the org with
            // the given regex
            if (duplicateList != null && !duplicateList.isEmpty()) {
                String logDuplicates = "Found duplicates from the classes fetched from the regex: " + regex
                        + ". Skipping multiple execution/code coverage computation of these test class/source class(es) :";
                for (int i = 0; i < duplicateList.size(); i++) {
                    duplicateApexClassMap.put(duplicateList.get(i), apexClassMap.get(duplicateList.get(i)));
                    logDuplicates += " " + apexClassMap.get(duplicateList.get(i)) + ",";
                }
                LOG.info(logDuplicates);
            }

            return uniqueClassesAsArray;
        }
        return classesAsArray;
    }

Notice that in the first few lines of this method, it set the "namespace" variable to null, and then calls QueryConstructor.generateQueryToFetchApexClassesBasedOnRegex, passing it a null value for the namespace. In my case, my "regex" for specifying test classes is "TomPackage.fflib_*Test". Ultimately this regex gets converted into the following SOQL:

SELECT Id , Name FROM ApexClass WHERE NamespacePrefix =null AND Name like 'TomPackage.fflib_%Test'

This is a bug. I'm going to file a new issue against this.

tfuda commented 8 years ago

@TedHusted I filed an issue against this namespace issue and submitted a pull request: https://github.com/forcedotcom/ApexUnit/pull/31

pmedapuram commented 8 years ago

@tfuda Yes, there was a plan to implement the feature to test ApexClasses that belong to a Namespace prefix. However, it was not implemented because of some of the additional discussion that was to happen here. A quick fix was instead implemented to always look for the default namespace. (to unblock @tfuda)

@TedHusted We certainly have this in our backlog to add this feature (https://github.com/forcedotcom/ApexUnit/issues/23) and created an issue for this.

Thank you for the pull request @tfuda , we will review the PR and test it for both manifest file and regex.

tfuda commented 8 years ago

@pmedapuram My pull request only addresses the regex story. I did not look at the manifest file handling.

TedHusted commented 8 years ago

I switched orgs, and I've gotten back my first ApexUnitReport.html -- sweet!