Project

General

Profile

Support #9446

compatibility test PUT-DOUBLE

Added by Greg Shah over 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Delia Mitric
Target version:
-
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
production:
No
env_name:
topics:

History

#1 Updated by Greg Shah over 1 year ago

Check the PUT-DOUBLE tests in Testcases to ensure they are complete and comprehensive. Add tests if needed. Convert and run the tests. Fix any issues as needed until the test pass completely.

#2 Updated by Alexandru Lungu over 1 year ago

  • Assignee set to Delia Mitric

#3 Updated by Delia Mitric over 1 year ago

  • Status changed from New to WIP

#4 Updated by Delia Mitric over 1 year ago

  • % Done changed from 0 to 30
  • reviewer Octavian Adrian Gavril added

Because I didn't find any test class that tests the functionality of PUT-DOUBLE statement, I've created a new class TestPutDouble.cls that contains more @Test methods.

The problem is that this tests are working in 4GL, but after I've converted the code and run it, a part of them don't work anymore.
I noticed the problem comes from the message of the errors.
For example, in 4GL, this code is working:

    @Test.
     method public void testFunctionMemptrPositionZero():
        define variable mem as memptr no-undo.

        // Position is 0
        set-size(mem) = 10.
        put-double(mem, 0) = 2.3 no-error.
        support.test.AssertExt:Error(1830, "Byte position for PUT-BYTE, GET-BYTE and other raw functions must be 1 or greater. (1830)").

     end method.

but after I converted it and run it, I receive this error:
testFunctionMemptrPositionZero ✘ Statement expected to throw error with message like 'Byte position for PUT-BYTE, GET-BYTE and other raw functions must be 1 or greater. (1830)' at index 1 but got '** Byte position for PUT-BYTE, GET-BYTE and other raw functions must be 1 or greater. (1830)'.

The converted java code for this method is:

@LegacySignature(type = Type.METHOD, name = "testFunctionMemptrPositionZero")
   @Test(order = 4)
   public void testFunctionMemptrPositionZero()
   {
      memptr mem = TypeFactory.memptr();

      internalProcedure(TestPutDouble.class, this, "testFunctionMemptrPositionZero", new Block((Body) () -> 
      {
         //  Position is 0
         mem.setLength(10);
         silent(() -> mem.setDouble(decimal.fromLiteral("2.3"), 0));
         com.goldencode.testcases.support.test.AssertExt.error(new integer(1830), new character("Byte position for PUT-BYTE, GET-BYTE and other raw functions must be 1 or greater. (1830)"));
      }));
   }

I have the same problem with error: "Unable to evaluate expression with UNKNOWN value in argument. (4391)".

Also, I run an already written test class: /home/dmm/gcd/testcases/testcases/src/com/goldencode/testcases/TestGetDouble.java and for the "Unable to evaluate expression with UNKNOWN value in argument. (4391)" error, I receive:
testFunctionRaw ✘ Statement expected to throw error with message like 'Unable to evaluate expression with UNKNOWN value in argument. (4391)' at index 1 but got '** Unable to evaluate expression with UNKNOWN value in argument. (4391)'.

Should I consider this tests as passed or should I look into it?

#5 Updated by Delia Mitric over 1 year ago

  • reviewer Alexandru Lungu added
  • reviewer deleted (Octavian Adrian Gavril)

#6 Updated by Alexandru Lungu over 1 year ago

Delia, please look into these mismatches. The goal is to fix FWD Java code to make it 100% compatible with 4GL, including error messages. Fin there the error message is constructed in FWD and make it like in 4GL.

Short notice: the customer code can retrieve this error message and do something like if (errMsg.startsWith("**)) .... else .... (psuedocode). In FWD it will lead to then-branch being executed, while in 4GL it will lead to else-branch being executed. My point: even if the things are "very similar", the execution path can split depending on this little mismatch. That is why we really need 101% compatibility (the trailing 1% is intentional to emphasis the importance).

#7 Updated by Delia Mitric over 1 year ago

  • Status changed from WIP to Review
  • % Done changed from 30 to 100

Committed my solution to testcases
I've added a new test class tests.base_language.builtin_functions.functionality.TestPutDouble.cls that tests PUT-DOUBLE functionality.

Committed my solution for errors at running to 9446a revision 15653.

I modified BinaryData.java file in order to solve the errors mentioned before. In genIndexError and genUnknownArgError methods, I modified the calls to ErrorManager.recordOrThrowError method by setting prefix parameter to false. This parameter, if is set to true, causes "** " to be appended to the original error text in buildErrorText method from ErrorManager.java class.

Initial code:

public static void genIndexError()
   throws ErrorConditionException
   {
      String err = "Byte position for PUT-BYTE, GET-BYTE and other" +
                   " raw functions must be 1 or greater";

      ErrorManager.recordOrThrowError(1830, err);
   }

private void genUnknownArgError()
   throws ErrorConditionException
   {
      String err = "Unable to evaluate expression with UNKNOWN value in argument";
      ErrorManager.recordOrThrowError(4391, err);
   }

Modified code:

public static void genIndexError()
   throws ErrorConditionException
   {
      String err = "Byte position for PUT-BYTE, GET-BYTE and other" +
                   " raw functions must be 1 or greater";

      ErrorManager.recordOrThrowError(1830, err, false);
   }

private void genUnknownArgError()
   throws ErrorConditionException
   {
      String err = "Unable to evaluate expression with UNKNOWN value in argument";
      ErrorManager.recordOrThrowError(4391, err, false);
   }

#8 Updated by Alexandru Lungu over 1 year ago

  • % Done changed from 100 to 50
  • Status changed from Review to WIP

There are some adjacent changes that were committed. Please change them back and make a commit to get the value back. For local development, you can make a copy of the testcases project so your personal changes won't get caught up in the BZR work.

=== modified file 'deploy/client/junit.sh' (properties changed: -x to +x)
--- old/deploy/client/junit.sh    2024-05-06 18:58:14 +0000
+++ new/deploy/client/junit.sh    2025-01-20 15:00:43 +0000
@@ -24,7 +24,7 @@
       d  ) debug=$OPTARG ;;
       s  ) suspend="y" ;;
       t  ) prog="echo "$prog ; test="y" ;;
-      c  ) class="com.goldencode.testcases.tests.$OPTARG" ;;
+      c  ) class="com.goldencode.testcases.$OPTARG" ;;
       \? ) for i in "${usage[@]}"; do
               echo -e $i
            done
@@ -60,6 +60,6 @@
 fi

 # run the jUnit
-cmd="$prog $dtxt $lpath -jar /home/rfb/projects/junit-platform-console-standalone-1.9.0.jar $cpath --select-class $class" 
+cmd="$prog $dtxt $lpath -jar /home/dmm/gcd/testcases/testcases/deploy/lib.junit/junit-platform-console-standalone-1.9.2.jar $cpath --select-class $class" 
 $cmd

=== modified file 'deploy/server/prepare_dir_postgres.json'
--- old/deploy/server/prepare_dir_postgres.json    2025-01-15 19:00:11 +0000
+++ new/deploy/server/prepare_dir_postgres.json    2025-01-20 15:00:43 +0000
@@ -27,12 +27,12 @@
   "dbnames": "tstcasesdb",
   "tstcasesdb": {
     "dbtype": "postgres",
-    "dbuser": "fwd_user",
-    "dbuserpass": "user",
+    "dbuser": "fwd_admin",
+    "dbuserpass": "admin",
     "dbadmin": "fwd_admin",
     "dbadminpass": "admin",
     "collation": "en_US@iso88591_fwd_basic",
     "dbhost": "localhost",
-    "dbport": {dbport}
+    "dbport": 5434
   }
 }

=== modified file 'prepare_build.json'
--- old/prepare_build.json    2024-12-10 20:23:03 +0000
+++ new/prepare_build.json    2025-01-20 15:00:43 +0000
@@ -2,5 +2,5 @@
    "dbh2": false,
    "dbpostgres": true,
    "dbmariadb": false,
-   "dbport": 5432
+   "dbport": 5434
 }

As for the tests: they look quite comprehensive, good job.

I would be also interested to find out how this put-double integrates with other statements, more precisely get-byte. If the put-double populates 8 bytes, then lets see how get-byte is planning to extract that double byte-by-byte. Is the representation little-endian or big-endian? How are the negative double values represented? Also, please check that putting a double "pads" the bytes till that start position with ?.

Lastly, but most important, please check whether the encoding of the double values in 4GL are IEEE-754 (. I think so, but please do some unit tests for negative numbers, positive numbers, zero, etc. to check sign (1bit), exponent (11bits), mantissa (52bits).

#9 Updated by Delia Mitric over 1 year ago

I've added tests about padding and encoding and I also tried this:

@Test.
    method public void testFunctionRawEncodingStandardZeroNegativeNum():
        define variable rw as raw no-undo.
        define variable bytes as integer extent 8 initial [0, 0, 0, 0, 0, 0, 0, 0] no-undo.
        define variable i as integer no-undo.

        // "Negative" Zero
        put-double(rw, 1) = -0.0.
        repeat i = 1 to 8:
            Assert:Equals(bytes[i], get-byte(rw, i)).
        end. 

    end method.

This test works in Progress 4GL, but after conversion is failing with this error message: testFunctionRawEncodingStandardZeroNegativeNum ✘ Expected: 0 but was: 128.
The problem comes from the bit that represents sign. In 4GL it is ignored for -0.0 value, but after conversion isn't.
I'll debug to see where the problem comes from.

#10 Updated by Alexandru Lungu over 1 year ago

Nice catch! This should be fixed in FWD.

Question: are the 0.0 values signed in 4GL (aka 0.0 and -0.0 yields different representations)? If so, FWD should know that as well.
Also, can you yield -0.0 using expressions: -0.0 / 2, -1.0 + 1.0, 5.3 * -0.0 etc? In 4GL and FWD

I want to understand if put-double is wrong or the decimal data type in FWD.

#11 Updated by Delia Mitric over 1 year ago

0.0 and -0.0 don't have different representation in 4GL

// representations
define variable rw1 as raw no-undo.
define variable rw2 as raw no-undo.
define variable i as integer no-undo.

// positive
put-double(rw1, 1) = 0.0.
repeat i = 1 to 8:
    display get-byte(rw1, i). // will display 0 0 0 0 0 0 0 0
end.

// negative
put-double(rw2, 1) = -0.0.
repeat i = 1 to 8:
    display get-byte(rw2, i). // will display 0 0 0 0 0 0 0 0
end.

About the results of expressions that are using -0.0 value, I receive same results in 4GL as in FWD, so it seems the problem comes from put-double method in FWD - setDouble method.

define var a as decimal no-undo.
a = 2.2 * -0.0.
display a. // will display 0.0

#12 Updated by Alexandru Lungu over 1 year ago

I think this is reasonable, please adjust FWD as needed.

#13 Updated by Delia Mitric over 1 year ago

Committed new tests to testcases revision 1694

Committed to 9446a revision 15654

=== modified file 'src/com/goldencode/p2j/util/BinaryData.java'
--- old/src/com/goldencode/p2j/util/BinaryData.java    2025-01-20 14:11:44 +0000
+++ new/src/com/goldencode/p2j/util/BinaryData.java    2025-01-22 14:48:41 +0000
@@ -2070,7 +2070,11 @@
    throws ErrorConditionException
    {
       // TODO: check if this encoding is right, check if raw version is right
-      
+
+      // Check if data is -0.0 in order to make it 0.0 because in 4GL both values have same
+      // representations
+      data = (data == -0.0) ? 0.0 : data;
+
       // the value is encoded in 64-bits which is best treated as a long
       return setIntegerWorker(Double.doubleToRawLongBits(data), pos, 8, null, true);
    }

#14 Updated by Delia Mitric over 1 year ago

  • Status changed from WIP to Review

#15 Updated by Alexandru Lungu over 1 year ago

  • Status changed from Review to Internal Test

I am ok with the changes in 9446a.
Is there anything left to be tested?

#16 Updated by Delia Mitric over 1 year ago

Alexandru Lungu wrote:

I am ok with the changes in 9446a.
Is there anything left to be tested?

As far as I know, there isn't.

#17 Updated by Delia Mitric over 1 year ago

  • % Done changed from 50 to 100

#18 Updated by Alexandru Lungu over 1 year ago

  • Status changed from Internal Test to Test

Branch 9446a was merged into the trunk as revision 15705 and archived.

#19 Updated by Greg Shah about 1 year ago

  • Status changed from Test to Closed

Also available in: Atom PDF